当前位置: 首页 > news >正文

HTTP SSE 实现

参考:
SSE协议
SSE技术详解:使用 HTTP 做服务端数据推送应用的技术

一句概扩

SSE可理解为:服务端和客户端建立连接之后双方均保持连接,但仅支持服务端向客户端推送数据。推送完毕之后关闭连接,无状态行。

下面是基于libhv实现的SSE

SSE server
int Handler::sse(const HttpContextPtr& ctx) {// SSEvent(message) every 1shv::setInterval(10000, [ctx](hv::TimerID timerID) {static int ncount = 0;if (ctx->writer->isConnected()) {char szTime[DATETIME_FMT_BUFLEN] = {0};datetime_t now = datetime_now();datetime_fmt(&now, szTime);ctx->writer->SSEvent(szTime);if (++ncount >= 10) {//hv::killTimer(timerID);ctx->writer->close();ncount = 0;}} else {hv::killTimer(timerID);}});return HTTP_STATUS_UNFINISHED;
}
SSE client
typedef std::function<void(const std::string& sid, const std::string& sevent, const std::string& sdata, const unsigned int retry_ms)> sse_msg_cb;
HV_INLINE int sse(http_method method, const char* url, const sse_msg_cb& msg_cb, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders,const unsigned int timeout_s = -1) {hv::HttpClient cli;HttpRequest req;HttpResponse resp;req.url = url; //req.method = method;req.timeout = timeout_s; // 不超时if (&body != &NoBody) {req.body = body;}if (&headers != &DefaultHeaders) {req.headers = headers;}bool bstream = false;req.http_cb = [msg_cb, &bstream](HttpMessage* resp, http_parser_state state, const char* data, size_t size) {if (state == HP_HEADERS_COMPLETE) {if (resp->headers["Content-Type"] == "text/event-stream") {bstream = true;return 0;}}else if (state == HP_BODY) {/*binary body should check data*/// printf("%s", std::string(data, size).c_str());resp->body.append(data, size);if (!bstream) return 0;/*/n/n获取message*/size_t ifind = std::string::npos;while ((ifind = resp->body.find("\n\n")) != std::string::npos) {std::string msg = resp->body.substr(0, ifind + 2);resp->body.erase(0, ifind + 2);/*解析body,暂时不考虑多dataid:xxx\nevent:xxx\ndata:xxx\ndata:xxx\ndata:xxx\nretry:10000\n*/auto kvs = hv::splitKV(msg, '\n', ':');if (msg_cb && (kvs.count("id") || kvs.count("event") || kvs.count("data") || kvs.count("retry")))msg_cb(kvs.count("id") ? kvs["id"] : "", kvs.count("event") ? kvs["event"] : "", kvs.count("data") ? kvs["data"] : "",kvs.count("retry") ? atoi(kvs["retry"].c_str()) : 0);}}return 0;};return cli.send(&req, &resp);
}
测试Demo
 sse(HTTP_GET,"http://127.0.0.1:12900/sse", [](const std::string& sid, const std::string& sevent,const std::string& sdata, const unsigned int retry_ms) { printf("id:%s\r\nevent:%s\r\ndata:%s\r\nretry:%u\r\n\r\n",sid.c_str(),sevent.c_str(),sdata.c_str(),retry_ms);});

在这里插入图片描述


http://www.mrgr.cn/news/91761.html

相关文章:

  • ChromeDriver下载
  • 【从0做项目】Java音缘心动(1)———项目介绍设计
  • hive开窗函数边界值ROWS BETWEEN 和 RANGE BETWEEN区别
  • Debezium 报错:“The db history topic is missing” 的处理方法
  • 小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统,不需要降级 v1.0.91 (2025)
  • DeepSeek本地部署教程
  • rtconfig.cpython-313.pyc 在 .gitignore文件中写入 *.pyc 文件仍然没有被忽略?
  • 导入大模型产生的字符串的时候碰到的问题
  • 基于Python/Java的医院系统切换互联网医院深度编程对接探索
  • ai json处理提示词
  • 设计模式教程:解释器模式(Interpreter Pattern)
  • 前端如何把SEO优化做到极致✅
  • TOGAF之架构标准规范-信息系统架构 | 应用架构
  • AIGC视频生成明星——Emu Video模型
  • nginx ngx_http_module(7) 指令详解
  • 【Java八股文】08-计算机网络面试篇
  • 【数据挖掘】深度挖掘
  • 我们来学nginx -- work process
  • 【UDS诊断(ReadDataByIdentifier0x22服务)测试用例CAPL代码全解析①】
  • 【大语言模型_4】源码编译vllm框架cpu版