You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于使用nghttp2库实现Server Sent Events(SSE)的技术问询

nghttp2对Server Sent Events(SSE)的支持与实现思路

nghttp2本身支持基于HTTP/1.x实现SSE,因为SSE本质是HTTP/1.x协议下的长连接分块推送机制,而nghttp2库包含完整的HTTP/1.x服务器/客户端实现(不仅限于HTTP/2)。官方文档未专门提及SSE,是因为SSE并非HTTP/2特性(HTTP/2有原生的Server Push机制),但完全可以基于其HTTP/1.x API实现SSE功能。

实现核心要点

要实现SSE,你需要在服务器端完成以下关键步骤:

  1. 设置正确的响应头
    必须为响应添加以下HTTP头,确保客户端识别为SSE流:

    • Content-Type: text/event-stream
    • Cache-Control: no-cache
    • Connection: keep-alive
      nghttp2会自动处理Transfer-Encoding: chunked(HTTP/1.x分块传输是SSE的基础)。
  2. 分块发送SSE格式数据
    SSE的事件格式遵循规范,每个事件通常由data:字段开头,以空行结尾。例如:

    data: 这是一条SSE消息\n\n
    

    也可以添加id:(事件ID)或event:(事件类型)字段来丰富事件信息:

    id: 123
    event: update
    data: 状态已更新\n\n
    
  3. 基于nghttp2的HTTP/1.x API实现推送循环
    在请求处理回调中,先提交响应头,然后进入循环,周期性生成SSE格式数据并通过nghttp2的API发送,直到客户端断开连接。

代码示例框架

以下是基于nghttp2 1.56.0-DEV版本的服务器端实现简化示例:

#include <nghttp2/nghttp2.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

// 请求处理回调
int on_request(nghttp2_http_server *server, nghttp2_http_session *session,
               const nghttp2_http_req *req, void *user_data) {
  // 仅处理指定SSE请求路径
  if (strcmp(req->path, "/sse") != 0) {
    nghttp2_http_server_response(session, 404, NULL, 0, NULL, 0);
    return 0;
  }

  // 设置SSE响应头
  nghttp2_nv headers[] = {
    NGHTTP2_NV("Content-Type", "text/event-stream", NGHTTP2_NV_FLAG_NONE),
    NGHTTP2_NV("Cache-Control", "no-cache", NGHTTP2_NV_FLAG_NONE),
    NGHTTP2_NV("Connection", "keep-alive", NGHTTP2_NV_FLAG_NONE),
  };

  // 提交200响应头
  nghttp2_http_server_response(session, 200, headers, sizeof(headers)/sizeof(nghttp2_nv), NULL, 0);

  // 周期性推送SSE事件
  int count = 0;
  char buf[256];
  while (1) {
    // 检查客户端连接状态
    if (nghttp2_http_session_is_closed(session)) {
      break;
    }

    // 构造SSE事件内容
    snprintf(buf, sizeof(buf), "data: 第%d条SSE消息\n\n", ++count);

    // 提交数据块并发送
    nghttp2_data_provider data_prd = {NULL, NULL};
    nghttp2_session_submit_data(session, NULL, buf, strlen(buf), 0, &data_prd);
    nghttp2_session_send(session);

    // 模拟1秒推送间隔
    sleep(1);
  }

  return 0;
}

int main() {
  nghttp2_http_server server;
  int rv;

  // 初始化HTTP服务器(默认兼容HTTP/1.x与HTTP/2)
  rv = nghttp2_http_server_init(&server, NULL);
  if (rv != 0) {
    fprintf(stderr, "服务器初始化失败: %d\n", rv);
    return 1;
  }

  // 绑定请求处理回调
  nghttp2_http_server_set_on_request_callback(&server, on_request, NULL);

  // 监听8080端口
  rv = nghttp2_http_server_listen(&server, "0.0.0.0", 8080, 0);
  if (rv != 0) {
    fprintf(stderr, 端口监听失败: %d\n", rv);
    nghttp2_http_server_free(&server);
    return 1;
  }

  // 启动服务器事件循环
  nghttp2_http_server_run(&server);

  nghttp2_http_server_free(&server);
  return 0;
}

注意事项

  • 编译时需链接nghttp2库,例如:gcc sse-server.c -o sse-server -lnghttp2。
  • SSE仅适用于HTTP/1.x连接,客户端发起SSE请求时会自动使用HTTP/1.x协议(SSE不兼容HTTP/2)。
  • 生产环境中需补充错误处理、超时管理逻辑,避免无效循环占用资源。

内容的提问来源于stack exchange,提问作者Michael Roeper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:51:21