C++中的Server-Sent Events:无需魔法和多余库的实时通信

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么普通HTTP请求就像寄信,而SSE就像实时电报



想象一下:你在等待网站上新评论的通知。你每5秒刷新一次页面。服务器每次都返回一大堆HTML、CSS、图片——然后到最后,你才看到:“没有新评论”。熟悉吗?这叫做轮询(polling)。它能工作,但消耗流量并给服务器带来负担。



现在想象另一个场景:你打开一个页面,一秒钟后页面上出现一条消息:“瓦西里留下了一条评论:‘好文章!’”。无需刷新,无需额外请求。服务器自己“推送”数据给你。这就是Server-Sent Events (SSE)——一种允许服务器通过普通HTTP连接向客户端发送事件流的技术。



在本文中,我们将探讨如何在不使用重型框架的情况下,用纯C++实现SSE。您将了解为什么C++中的Server-Sent Events是监控、股票行情、聊天通知以及任何需要实时单向数据传输任务的绝佳选择。



Server-Sent Events如何工作?协议解析



SSE是HTML5规范的一部分。客户端打开一个普通的HTTP连接,并告诉服务器:“我准备好监听事件了”。服务器不会关闭连接,而是开始以特殊的text/event-stream格式发送数据。



消息格式极其简单:



data: 这是事件文本



每个事件以data:开头,以双换行符结束。可以添加id:用于标识,event:用于事件类型,以及retry:用于指定重新连接的时间(以毫秒为单位)。



一个完整流的示例:



id: 42event: new_messagedata: {"user": "瓦西里", "text": "你好!"}

id: 43event: pingdata: 服务器存活



客户端(浏览器或任何应用程序)处理这些行并生成JavaScript事件。一切巧妙之处都如此简单。



SSE vs WebSocket:何时选择哪个?



当谈到实时通信时,许多人首先想到的是WebSocket。让我们比较一下:



  • WebSocket — 双向通信。客户端和服务器都可以发起交换。需要单独的协议(ws://),需要通过代理,经常被企业防火墙阻止。
  • SSE — 单向通信(服务器 → 客户端)。基于普通HTTP工作。断开时自动重新连接。可以轻松通过任何代理。


如果您的任务是向客户端发送通知,而不是等待其命令,那么C++中的Server-Sent Events是一个优雅且简单的解决方案。无需引入重型库,无需编写复杂处理程序。



从零开始用C++编写SSE服务器



实现所需的最少内容:套接字和HTTP处理。在实际项目中,人们使用Boost.Beast或libmicrohttpd,但为了理解本质,我们将使用纯C++和POSIX套接字编写一个简单的服务器。



我们的服务器将:

  • 接受来自客户端的HTTP请求
  • 判断客户端是否需要SSE(通过Accept: text/event-stream头)
  • 每2秒发送一个包含当前时间的事件流


步骤1:创建套接字并监听端口



#include <iostream>#include <string>#include <cstring>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#include <thread>#include <chrono>#include <sstream>

void handle_client(int client_socket) { // 请求缓冲区 char buffer[4096] = {0}; read(client_socket, buffer, 4096); // 检查是否为GET请求

博客

书籍推荐