ESP32S3内网实现 WebSocket

WebSocket 是一种网络通信协议,它提供了在单个 TCP 连接上进行全双工、双向通信的通道。它是为了在 Web 浏览器和服务器之间实现实时、高效的数据交换而设计的,是传统 HTTP 轮询技术的一种强大替代方案。

  1. 持久连接:

    • 与 HTTP 请求不同(每个请求都需要建立和关闭连接),WebSocket 在客户端(如浏览器)和服务器之间建立一次连接,之后该连接会保持打开状态
    • 只要双方愿意,这个连接可以持续存在,允许数据在任何时候双向流动。
  2. 全双工通信:
    • 一旦连接建立,客户端和服务器可以同时、独立地向对方发送数据
    • 服务器可以在有新信息时立即“推送”给客户端,无需客户端先发起请求。客户端也可以随时发送数据给服务器。
  3. 低开销:
    • 建立连接时(通过一个特殊的 HTTP 握手过程),后续的数据交换使用非常轻量级的数据帧(frames) 进行传输。
    • 相比于 HTTP 轮询(不断发送请求检查更新)或长轮询(挂起请求等待更新),WebSocket 大大减少了网络带宽消耗和延迟(尤其是往返延迟)。
  4. 基于事件驱动:
    • 客户端和服务器端的代码通常基于事件模型编写。例如:

      • 当连接成功建立时,触发 onopen 事件。
      • 当收到对方发送的消息时,触发 onmessage 事件。
      • 当连接关闭时,触发 onclose 事件。
      • 当发生错误时,触发 onerror 事件。
  5. 握手过程:
    • WebSocket 连接始于一个特殊的 HTTP 请求(称为“握手”)。这个请求包含一个 Upgrade: websocket 头,表明客户端希望将连接升级到 WebSocket 协议。
    • 如果服务器支持 WebSocket,它会返回一个 HTTP 101(Switching Protocols)响应,同意升级协议。
    • 握手成功后,初始的 HTTP 连接就被“升级”为 WebSocket 连接,后续的通信都使用 WebSocket 协议的数据帧进行,不再是 HTTP。
  6. 支持文本和二进制数据:
    • WebSocket 可以高效地传输纯文本(如 JSON、XML)和二进制数据(如图片、音频、视频流、自定义协议数据)。

为什么需要 WebSocket? (对比 HTTP)

  • HTTP 的局限性:

    • 单向性: 传统 HTTP 是“请求-响应”模型。客户端发起请求,服务器返回响应。服务器无法主动向客户端推送数据。
    • 高延迟: 实现“实时”效果(如聊天、游戏、实时数据更新)需要客户端不断轮询服务器(频繁发送请求询问是否有新数据),这会产生大量不必要的请求和显著的延迟。
    • 高开销: 每个 HTTP 请求/响应都包含完整的 HTTP 头信息(如 cookies、user-agent 等),对于频繁的小数据更新来说,这些头部信息是巨大的开销。
  • WebSocket 的优势:
    • 真正的实时性: 服务器可以瞬间将新数据推送给所有连接的客户端。
    • 低延迟: 省去了建立连接的开销和轮询的等待时间。
    • 低带宽消耗: 连接建立后,数据传输帧的头部信息极小。
    • 高效的双向通信: 适合需要频繁、快速交互的应用。

典型应用场景:

  • 实时聊天应用: 消息的即时发送和接收。
  • 在线多人游戏: 玩家动作和游戏状态的实时同步。
  • 协作编辑工具: 多个用户同时编辑文档时的实时更新。
  • 实时数据仪表盘: 股票行情、体育赛事比分、服务器监控、物联网设备数据流。
  • 在线拍卖/博彩: 实时出价和结果更新。
  • 基于位置的服务: 实时位置共享和更新。
  • 社交网络实时通知。

关键点总结:

  • 协议: WebSocket 是一个独立的协议 (ws:// 或加密的 wss://)。
  • 连接: 持久、长连接。
  • 通信模式: 全双工、双向。
  • 效率: 低延迟、低开销。
  • 目的: 实现 Web 应用和服务器的实时、高效双向通信。

简单来说: WebSocket 就像在浏览器和服务器之间打开了一条专用的电话线。一旦拨通(握手成功),双方可以随时说话(发送数据)和收听(接收数据),不需要反复拨号(建立连接),通话(数据传输)也非常高效。这使得构建实时交互性强的 Web 应用变得容易且高效。

通过ESP32S3实现,首先确认功能实现:

ESP32S3作为服务器配置成AP模式

客户端(手机,电脑)连接ESP32S3热点形成局域网(内网)

连接web界面展示:

menuconfig选项配置:

开启WebSocket 服务器支持

增大网址请求头长度

代码部分讲解:

从主函数入口就可以管中窥豹,从宏观看待流程

void app_main(void) {
// 初始化非易失性存储器
ESP_ERROR_CHECK(nvs_flash_init());
// 初始化软AP模式
wifi_init_softap();
// 启动WebSocket服务器
start_websocket_server();
初始化非易失性存储器
初始化软AP模式
启动WebSocket服务器
}

总共分三个部分

  1. 初始化非易失性存储器(NVS)
  2. 初始化软AP模式(配置ESP32S3为AP模式,配置内网传输环境)
  3. 启动WebSocket服务器(处理连接事件)

核心在第三部分,先处理客户端发起的http get请求,将其升级为WebSocket通信

// 启动WebSocket服务器
static httpd_handle_t start_websocket_server(void) {
// 声明一个httpd_handle_t类型的变量server,用于存储httpd_start函数返回的句柄
httpd_handle_t server = NULL;
// 声明一个httpd_config_t类型的变量config,用于存储httpd_start函数需要的配置参数
httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // 设置uri匹配函数为httpd_uri_match_wildcard
config.uri_match_fn = httpd_uri_match_wildcard;
// 设置最大uri处理器的数量为16
config.max_uri_handlers = 16;
// 设置最大响应头的数量为16
config.max_resp_headers = 16;
// 设置最大打开的socket数量为4
config.max_open_sockets = 4; // 调用httpd_start函数启动http服务器,并将返回的句柄存储在server变量中
if (httpd_start(&server, &config) == ESP_OK) {
// 声明一个httpd_uri_t类型的变量ws_uri,用于存储websocket的uri信息
httpd_uri_t ws_uri = {
.uri = "/ws",
.method = HTTP_GET,
.handler = ws_handler,//握手阶段,成功后升级通信协议为WebSocket
.user_ctx = NULL,
.is_websocket = true
};
httpd_register_uri_handler(server, &ws_uri); httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_get_handler,//// 处理根路径的GET请求,发送html文件
.user_ctx = NULL
};
httpd_register_uri_handler(server, &index_uri);
}
return server;
}

在这里服务器(ESP32S3)发送html网页文件给客户端,客户端在网页实现WebSocket接口调用

源码分享:

https://github.com/jianzhiji/blog/blob/main/ESP32S3_websocket.zip

结束语:

如果文章对你有所帮助,可以帮我点一下左下角推荐该文,万分感谢

博主目前在广州,深圳寻找找嵌入式软件实习。

如有大佬(HR,BOSS)能推荐实习,恳请私信小弟给个机会,帮帮小弟,万分感谢!!!

联系方式:博文侧边栏微信二维码

ESP32S3内网实现 WebSocket的更多相关文章

  1. 使用Portainer集中管理多地域内网运行的Docker实例

    1. 单机运行的Docker 容器化部署是现在进行时,开源应用大多数支持容器化部署 在少量机器的场景下往往采用docker cli 和 docker-compose管理,进行"单机式管理&q ...

  2. 基于Yarp实现内网http穿透

    Yarp介绍 YARP是微软开源的用来代理服务器的反向代理组件,可实现的功能类似于nginx. 基于YARP,开发者可以非常快速的开发一个性能不错的小nginx,用于代理http(s)请求到上游的ht ...

  3. cpolar——安全的内网穿透工具

    什么是cpolar? cpolar是一种安全的内网穿透云服务,它将内网下的本地服务器通过安全隧道暴露至公网,使得公网用户可以正常访问内网服务. 它能用在哪些场景? 微信公众号开发,实时断点调试微信消息 ...

  4. 【新晋开源项目】内网穿透神器[中微子代理] 加入 Dromara 开源社区

    1.关于作者 dromara开源组织成员,dromara/neutrino-proxy项目作者 名称:傲世孤尘.雨韵诗泽 名言: 扎根土壤,心向太阳.积蓄能量,绽放微光. 拘浊酒邀明月,借赤日暖苍穹. ...

  5. 使用frp进行内网穿透

    frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP.UDP.HTTP.HTTPS 等多种协议.可以将内网服务以安全.便捷的方式通过具有公网 IP 节点的中转暴露到公网. frp is a ...

  6. 用SSH访问内网主机的方法

    如今的互联网公司通常不会直接自己直接配主机搭建服务器了,而是采用了类似阿里云的这种云主机,当应用变得越来越大了之后,就不可避免地增加主机,而出于成本考虑,不可能给每一台主机都分配公网带宽,所以实际的情 ...

  7. 内网穿透神器ngrok

    相信做Web开发的同学们,经常会遇到需要将本地部署的Web应用能够让公网环境直接访问到的情况,例如微信应用调试.支付宝接口调试等.这个时候,一个叫ngrok的神器可能会帮到你,它提供了一个能够在公网安 ...

  8. 内网劫持渗透新姿势:MITMf简要指南

    声明:本文具有一定攻击性,仅作为技术交流和安全教学之用,不要用在除了搭建环境之外的环境. 0×01 题记 又是一年十月一,想到小伙伴们都纷纷出门旅游,皆有美酒佳人相伴,想到这里,不禁潸然泪下.子曰:& ...

  9. LCX端口转发实现内网突破

    工具:lcx.exe 原理:当目标主机仅开放了web服务,而该服务又仅能供内网用户使用,外网用户根本无法直接访问.因此想要让外网用户能能够访问局域网中的系统服务,必须进行端口映射等操作才行.其原理就是 ...

  10. 外网访问内网工具ngrok tunnel 使用总结

    需求分析 在软件开发测试过程中,我们会经常遇到需要网站部署测试.给客户演示.APP开发的调试这样的需求.通常的做法是申请一个域名和空间,将网站放到外网上给客户演示. 这种方法确实可行不过会有两点不好, ...

随机推荐

  1. 【Matlab】基于KDtree的最近邻搜索和范围搜索

    摘要:介绍Matlab的rangesearch()函数和knnsearch()函数. rangesearch() -- 根据给定k-维数据集,返回指定距离范围内的所有数据点 knnsearch() - ...

  2. python 字典使用

    整理很好的文章 文章复制链接: https://mp.weixin.qq.com/s/Aj65A-uuTaARW3vvYTxvzQ 1.检查键是否存在于字典中 def key_in_dict(d, k ...

  3. 附035.Kubernetes_v1.25.3高可用部署架构二

    目录 部署组件 kubeadm介绍 kubelet介绍 kubectl介绍 方案概述 方案介绍 部署规划 节点规划 主机名配置 变量准备 互信配置 环境初始化 部署高可用组件 HAProxy安装 Ke ...

  4. 【P5】Verilog搭建流水线MIPS-CPU

    课下 Thinking_Log 1.为何不允许直接转发功能部件的输出 直接转发会使一些组合逻辑部件增加新的长短不一的操作延迟,不利于计算设置流水线是时钟频率(保证流水线吞吐量?). 2.jal中将NP ...

  5. nuxt.js 使用 Typescript 在 VSCode 报错: File 'xxx/components/Logo.vue' is not a module. Vetur(2306)

    nuxt.js 生成的默认文件 components/Logo.vue 源码大概如下: 1 <template> 2 <svg 3 class="NuxtLogo" ...

  6. 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)

    FRP 是 Github 上开源的一款内网穿透工具,点击前往项目地址,该项目分为 frps 服务端和 frpc 客户端,通过在拥有公网 IP 的服务器上搭建服务端,然后在被穿透的机器上安装客户端,配置 ...

  7. 微信小程序云函数

    小程序开发云环境设置 注意事项 每一个云函数都是一个独立的 nodeJS 项目.所以每个云函数下都有 package.json 文件 错误 前端操作数据库 1 指引 2 新建集合 3 新增记录 4 查 ...

  8. Vue3生命周期钩子函数深度解析:从源码到实战的万字指南

    一.Vue3生命周期革新特性 相较于Vue2,Vue3通过Composition API带来了更灵活的生命周期管理方式.通过onBeforeMount等函数注册钩子时,实际是通过injectHook方 ...

  9. JOKER智能可视化平台 20250204版本更新说明

    本次 JOKER 低代码平台更新涵盖了代码生成.环境变量.可视化开发工具等多个关键领域的优化与新增功能,致力于为开发者提供更高效.更安全.更便捷的开发体验.同时,服务端功能的正式发布以及核心升级,进一 ...

  10. spring 事务失效的 12 种场景

    看这个:https://blog.csdn.net/hanjiaqian/article/details/120501741里面有12种失效场景以及如何解决. 在 spring 中为了支持编程式事务, ...