你好,我是吴老师。这份是给你自己读的——不用等我讲,看不懂就整段复制给 AI,加一句"请一次只解释一个概念,讲完问我一个小问题"。
读完之后,你应该能:
- 说出蓝牙对讲(第 40 课)和网络聊天室最大的区别是"多了一个谁";
- 明白板子为什么必须先连路由器,连上后它"有"了哪三样身份;
- 说清"发消息"是上传到"信箱"、"收消息"靠定时轮询,以及轮询的代价。
用时:约 60 分钟。 准备:两块同型号触摸屏板 + 同一台路由器 + 一根 USB 线;WiFi 账号密码只放本机
config.real.h,别写进任何公开代码。
一、让板子隔着一个"信箱"聊天
第 40 课我们做了蓝牙对讲机——两块板不连 WiFi、靠蓝牙隔空传语音。但它有个限制:蓝牙只能"附近",必须挨得很近,还是一对一。
今天问一个"过瘾"的问题:
如果两块板都连上同一台路由器,能不能像微信那样——把文字"寄"到一个所有人共用的"信箱",另一块板隔一会儿去"取信"?哪怕隔几个房间、甚至不在同时在线,也能聊。
能。这个"信箱"就是一个跑在局域网里的服务器。今天我们就来玩明白它。
先看现象:烧录 demo01_wifi_sta,板子连上路由器,屏幕亮出自己的 IP 和 MAC——这是"网络聊天室"的接入起点。
二、我观察到的现象
| 现象 | 勾选 |
|---|---|
| 屏幕先显示"Start connecting to WiFi..." | |
| 串口里一个个"."在慢慢刷 | |
| 连上后屏幕变绿"Connection successful!!!" | |
| 屏幕打出三行:SSID、IP、MAC | |
| 密码填错时:红字"connection failed!!!"一闪一闪 |
三、板子"入室"后,到底有了什么
连接成功后,屏幕上的 SSID / IP / MAC 让板子成了网里的一个"住户":
| 身份 | 像什么 | 干什么用 |
|---|---|---|
| SSID | 连的是哪个网 | 告诉你它进了哪张局域网 |
| IP | 网里的门牌号 | 数据靠它找到这块板 |
| MAC | 出厂身份证 | 写死的、全球唯一 |
有这三样,板子才是一个"能被找到、也能去找别人"的住户。 要聊天,先入室——这就是 WiFi.begin() 替你做的基本功。
四、从"入室"到"聊天室":多了一个信箱
两块板怎么说话?它比蓝牙对讲多了一个关键的中间人:
| 环节 | 谁在干 | 哪个课学过 |
|---|---|---|
| 认路拿身份 | WiFi.begin / WiFi.localIP | 第 17 课 |
| 怎么可靠送去 | TCP/UDP 与端口 | 第 18 课 |
| 怎么"问服务器" | HTTP 请求 + JSON | 第 19 课 |
| 把消息寄出去 | 上传到服务器"信箱" | 本课重点 |
| 取回别人的消息 | 定时"轮询"去拉 | 本课重点 |
| 想更实时 | 服务器主动"推"(长连接) | 第 18 课延伸 |
一句话:聊天室 = 两块板连同一个路由器 + 一个共用的"信箱"(服务器)+ 一方"给"、一方"取"。
五、信箱,就是"你先放,我过会儿来取"
把网里那个服务器,想成大楼一层的收发室。
- 发消息=跑过去,把信投进写着"给我朋友"的格子(上传);
- 收消息=每隔一会儿主动跑过去问"有没有我的新信?"有就取走(轮询);
- 因为是你自己去问、自己取,所以哪怕朋友当时不在,信也躺在收发室里等你——这是它能"跨房间、不必同时在线"的原因。
⚠️ 比喻要有边界:"信箱/收发室"是讲服务器把消息存着,客户端靠"问一次取一次"拿消息,不是真有一栋楼。它跟蓝牙对讲最大的不同不是"传得快",而是多了一个"中间人"(服务器),所以能共用、能存档、不必同时在线;代价是多一道"来回问",慢一点、费一点网络。
六、两个代码名,够了
1. WiFi.begin(名字, 密码)——"板子以学生的身份,去连那台路由器"
WiFi.mode(WIFI_STA); // 这课板子当"学生"(STA),去连别人的网
WiFi.begin(ssid, password); // 喊出要连哪个网、用哪把钥匙
while (WiFi.status() != WL_CONNECTED) { ... } // 等路由器回话,没连上继续等
这是聊天室的第一块地基:不连上路由器,两块板根本不在一张网里,后面寄信、取信全免谈。
2. WiFi.status()——"问板子:你连上了吗?"
WiFi.status() == WL_CONNECTED → 连上了(程序里这个条件成立才继续)
WiFi.status() != WL_CONNECTED → 还没连上
连上后还能用:
WiFi.localIP() → 报出我的"门牌号"(IP)
WiFi.macAddress() → 报出我的"身份证"(MAC)
demo01 里那段 while 循环,就是不停问板子"连上了吗";串口里的".",是没连上就吐一个点。连上了才把 IP、MAC 打到屏幕。
最该记住的:WiFi.begin() 让板子入室(连路由器),WiFi.status() 让板子知道连没连上;拿到 IP/MAC,就是这张网里的"身份三件套"。
七、下一步:发消息上传、收消息轮询
demo01 只会"入室报身份"。让两块板真聊上,还要补两件事(都是第 19 课本领,往"聊天"上用):
- 发消息 = HTTP 上传:
http.POST(...)把你的一行字 + 昵称,打包成 JSON,寄到服务器"信箱"; - 收消息 = 定时轮询:每隔几秒
http.GET(...)问服务器"有新信吗?",取下来显示。
| 现象 | 勾选 |
|---|---|
| 发一条,显示在屏幕底部"我说了什么" | |
| 隔几秒,对方回复自己"冒"了出来 | |
| 对方关机,再发,它开机后仍能看到 | |
| 字越多、越频繁,板子联网越"忙" |
轮询要代价。 每隔 3 秒问一次,就得每隔 3 秒发一次请求——问得越勤,消息越新鲜,但网络越忙、板子越累;问得太久,又感觉"不实时"。想要"对方一发、我立刻收到",就用第 18 课那条一直连着不放的 TCP 长连接,让服务器**主动"推"**给我。轮询是"我去问",推送是"你推给我"——一组"新鲜度 vs 省流量"的选择题。
八、改一个条件:把轮询频率改一改
思想实验:把"每隔 3 秒问一次"改成"每隔 0.5 秒"或"每隔 2 分钟",会怎样?
| 我改了什么 | 我预测 | 实际 |
|---|---|---|
| 轮询改成每 0.5 秒 | 消息几乎实时,但网络和板子一直"忙",费流量更费电 | |
| 轮询改成每 2 分钟 | 很省事,但两条消息间可能隔很久,感觉"不实时" |
"多久问一次"就是"新鲜度"和"省流量"之间的旋钮。 真聊天软件不会傻傻一直问——要么调好周期,要么干脆双方"推送"。
九、过关检查
- 蓝牙对讲(第 40 课)和网络聊天室最大的区别是什么?"多了一个谁"?
- 板子为什么必须先连路由器?连上后它"有"了哪三样身份?
- "发消息"在程序里走哪一步?为什么说是"上传到信箱"?
- "收消息"为什么必须定时轮询?轮询太久/太勤分别怎样?
- 轮询和"推送"哪个更实时?推送靠第 18 课哪条路?
- 为什么双方"不必同时在线"也能聊?秘密藏在"信箱"的哪个特点里?
留下三样东西:你板子屏幕上那个 IP、你往"信箱"里"寄"的第一句话、"聊天室和蓝牙对讲差在哪"的一句话。
十、还能玩什么
| 作品方向 | 描述给 AI 的效果 | 再想想 |
|---|---|---|
| 多人聊天室 | 3 块板连一个信箱,谁都能发、谁都能看 | 消息要不要按昵称分组?多人同时发会乱序吗? |
| 有昵称的群聊 | 每条消息前显示"这是谁说" | 昵称和内容一起打包成 JSON? |
| 私聊小窗口 | 只让选的人看到你的消息 | 服务器怎么知道"私聊"该发给谁? |
| 实时表情轰炸 | 发个图标对方立刻看到 | 要"立刻",继续轮询还是改用"推送"? |
| 离线接收 | 对方关机你照发,它开机补看 | "信箱"把信存着——就是不用同时在线的原因 |
下节课预告:这一课让板子"隔着一个信箱"传了文字——离得远、能多人、能存档,但靠"轮询"还稍慢。下一课(第 42 课)回到"自己跟自己玩",做一件很好玩的东西:绘画软件,让这块触摸板变成你的随身画板。