查看: 1028|回复: 0

[Arduino] ESP32 Arduino教程:基于soft AP(热点)实现Websocket server

[复制链接]
ESP32教程的测试是使用集成在FireBeetle ESP32 开发板中的DFRobot的ESP-WROOM-32设备运行的。

简介
本文主要介绍如何在运行于soft AP模式的ESP32上设置Websocket server(服务器)。使用的软件架构是ESP32的Arduino内核。
设置Websocket server(服务器)所需要的代码在此前的这篇帖子:ESP32 Arduino教程:Websocket server(服务器)
中已经详细说明。本文直接使用相同的代码,详情不再赘述。本教程中用于测试的Python客户端也在上一篇帖子里进行了分析。
设置ESP32作为soft AP运行的相关代码,其详细说明也可以参考上一篇帖子ESP32 Arduino教程:Websocket server(服务器)

在本教程中,ESP32仅作为一台回发Websocket server(服务器)使用,它会将接受到的内容原封不动地回发给客户端。
因为ESP32作为soft AP运行,所以就不需要通过路由器提供外部WiFi以建立客户端与服务器之间的连接。
因此,运行Python代码的电脑就需要连接到ESP32提供的WiFi网络,以在两者之间透明地发送和接收数据。


Python代码
简介部分说过,我们将重用上一篇帖子:ESP32 Arduino教程:Websocket server(服务器) 介绍的Python websocket客户端代码。那篇帖子还提供了安装websocket-client模块的相关说明。

首先需要在代码中导入websocket和time模块。然后,建立一个WebSocket类的对象实例,通过调用该对象的connect方法将其连接到我们的ESP32 websocket server(服务器)。
请注意,为了成功连接到服务器,我们需要使用ESP32的正确IP地址。在本教程中,由于ESP32作为soft AP运行,所以我们需要使用它自己的IP地址,我们将在Arduino代码中将这个地址打印到串行控制台上。

[AppleScript] 纯文本查看 复制代码
import websocket

import time

 

ws = websocket.WebSocket()

ws.connect("ws://192.168.4.1/")

 


建立好连接之后,我们将通过循环将数据发送到服务器,然后获取服务器回发过来的响应。完成与服务器的交互之后,通过调用WebSocket对象的close方法以断开服务器连接。


Python websocket客户端的完整源代码如下所示。


[AppleScript] 纯文本查看 复制代码
import websocket[/align]
import time



ws = websocket.WebSocket()

ws.connect("ws://192.168.4.1/")



i = 0

nrOfMessages = 30



while i<nrOfMessages:

    ws.send("Soft AP mode: message nr " + str(i))

    result = ws.recv()

    print(result)

    i=i+1

    time.sleep(1)



ws.close()



Arduino代码
Arduino代码也和上一篇帖子里的代码非常相似:ESP32 Arduino教程:Websocket server(服务器)。首先,将WiFi.h和WebSocketServer.h库包含进来,前者主要用于设置我们的soft AP,后者则负责处理与Websocket相关的功能。


我们需要一个WiFiServer类的对象,以创建能够接收客户端连接的TCP服务器。这个类的构造函数有一个可选的端口输入参数,用于指定服务器将要监听的端口号。我们使用端口80。


然后,在我们的TCP服务器上新建一个Websocket server(服务器)。为了使用与Websocket相关的功能,我们需要一个WebSocketServer类的对象。封装函数(wrapper)将负责处理具体的Websocket协议,我们只需要考虑与客户端之间的数据交换即可。

在Arduino的setup函数中,首先打开一个串行连接,以便将接收自客户端的数据打印出来。

[AppleScript] 纯文本查看 复制代码
[/align]#include <WiFi.h>

#include <WebSocketServer.h>

 

WiFiServer server(80);

WebSocketServer webSocketServer;

 

const char *ssid = "MyESP32AP";

const char *password = "testpassword";

还有两点需要考虑,那就是所创建网络的名称(ssid)以及访问密码。


然后,调用WiFi外部变量(通过WiFi.h库包含进来)的softAP方法以对soft AP进行设置。在连接到路由器提供的WiFi网络时,我们使用的也是这个外部变量。


接下来,要打印ESP32的IP地址,我们需要调用同一个WiFi变量的softAPIP方法。有关在ESP32上设置soft AP的更多详情,请参阅此前的这篇帖子:ESP32 Arduino教程:通过软接入点(soft AP)实现HTTP服务器

[AppleScript] 纯文本查看 复制代码
Serial.begin(115200);

 

delay(4000);

 

WiFi.softAP(ssid, password);

Serial.println(WiFi.softAPIP());


在setup函数最后,我们需要对TCP服务器进行初始化。只需在先前声明的全局WiFiServer对象上调用begin方法即可。

[AppleScript] 纯文本查看 复制代码
server.begin();

在主函数中,我们将调用WiFiServer对象的available方法,以确认客户端是否已成功连接。


调用该方法将会返回一个WiFiClient类型的对象。为确认客户端是否连接成功,我们会调用该对象的connected方法。如果客户端成功连接,则该方法会返回true,否则将返回false。


客户端已连接成功的话,我们需要执行Websocket协议握手。只需在我们先前声明的全局WebSocketServer对象上调用handshake方法即可。


该方法的输入参数是我们所获得的WiFiClient对象,如果握手成功则该方法的返回值为true。


[AppleScript] 纯文本查看 复制代码
if (client.connected() && webSocketServer.handshake(client)) {

   // Exchanging data with the client

}



在条件判断代码部分,我们会声明一个变量,用作接收自客户端的数据缓冲区。只要客户端已连接,我们就循环接收数据、打印到串行控制台并将数据回发给客户端。


通过调用WebSocketServer对象的getData方法,即可从WebSocket获取数据。该方法不需要输入参数,其返回值是一个字符串(其中包含了所接收到的数据)。


为将数据回发给客户端,只需调用sendData方法并把数据作为其输入字符串传给它即可。在本例中,因为服务器就是一台回发服务器,所以要发送的数据就是先前接收的数据。


最终的源代码如下所示,其中包括了与客户端之间的数据交换。请注意,当前文提到的循环结束时,就意味着客户端已经断开,所以我们会把相关信息也打印到串行控制台。

[AppleScript] 纯文本查看 复制代码
#include <WiFi.h>

#include <WebSocketServer.h>



WiFiServer server(80);

WebSocketServer webSocketServer;



const char *ssid = "MyESP32AP";

const char *password = "testpassword";



void setup() {



  Serial.begin(115200);



  delay(4000);



  WiFi.softAP(ssid, password);

  Serial.println(WiFi.softAPIP());



  server.begin();

  delay(100);

}



void loop() {



  WiFiClient client = server.available();



  if (client.connected() && webSocketServer.handshake(client)) {



    String data;      



    while (client.connected()) {



      data = webSocketServer.getData();



      if (data.length() > 0) {

         Serial.println(data);

         webSocketServer.sendData(data);

      }



      delay(10); // Delay needed for receiving the data correctly

   }



   Serial.println("The client disconnected");

   delay(100);

  }



  delay(100);

}




测试代码
使用Arduino IDE对代码进行编译并上传到您的ESP32开发板,即可对代码进行测试。然后,打开IDE serial monitor并复制打印出来的IP地址。在您Python程序的connect方法中,应该使用此处所输出的IP地址。


一旦您的电脑检测到ESP32 WiFi网络,请直接连接即可。在Windows 8上的视图如下所示。

esp32-soft-ap-on-windows-8.png
图1 - Windows 8检测到ESP32 WiFi网络的视图(菜单语言为葡萄牙语)。


然后,运行Python代码。控制台上显示的输出结果如图2所示。和我们所预期的一样,发送到服务器的消息都被回发给了客户端。

2esp32-websocket-server-python-client-over-soft-ap.png
图2 - Python程序的输出结果。


在Arduino IDE serial monitor上,程序的输出结果如图3所示。客户端所发送的消息都被接收并打印到了串行控制台上。

3e.png
图3 - 串行控制台打印的数据(接收自客户端)。


注:本文作者是Nuno Santos,他是一位和蔼可亲的电子和计算机工程师,住在葡萄牙里斯本 (Lisbon)。
他写了200多篇有关ESP32、ESP8266的有用的教程和项目。

查看更多ESP32/ESP8266教程和项目,请点击 : ESP32教程汇总贴
英文版教程 : ESP32 tutorial




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail