实际上如果单纯的进行nginx sse 处理很简单,但是我们实际的场景存在数据访问控制以及数据处理
对于此问题,我们可以使用sse client 包装,然后同时将我们的请求endpoint 暴露为一个sse 服务
参考处理图

代码说明
- sse 服务
基于nodejs 开发的一个测试,基于express
const express = require('express');const { sseMiddleware } = require('express-sse-middleware');const app = express()app.use(sseMiddleware);app.get('/sse', (req, res) => {const sse = res.sse(); // `adding Response.sse()` funcitonlet count = 0;setInterval(() => {sse.send(String(count++));}, 1000);});
app.get('/ssev2', (req, res) => {res.writeHead(200,{'Content-Type':'text/event-stream'});setInterval(() => {res.write(`event:xxxx\ndata:${new Date().toLocaleTimeString()}\n\n`)}, 1000);});
app.listen(3000);- nginx 处理
基于openresty 包含了一个token处理以及基于sse client 获取sse 服务的数据
nginx.conf
user root;master_process off;worker_processes 1;events {worker_connections 1024;}http {include mime.types;default_type text/html;lua_code_cache off;lua_package_path '/opt/lua/?.lua;;';real_ip_header X-Forwarded-For;resolver 127.0.0.11;server {listen 80;charset utf-8;proxy_set_header X-Forwarded-For $remote_addr;proxy_buffering off;proxy_cache off;proxy_set_header Connection '';proxy_http_version 1.1;chunked_transfer_encoding off;default_type text/html;location /ssev2 {# 代理标准请求proxy_pass http://sse:3000;}location / {default_type text/event-stream;# 访问控制access_by_lua_block {local token, err = ngx.req.get_headers()["token"]if token == nil thenngx.exit(ngx.HTTP_FORBIDDEN)end}// 内容处理,基于了sse clientcontent_by_lua_block {local sse = require "resty.sse"local cjson = require "cjson"local conn, err = sse.new()if not conn thenngx.say("failed to get connection: ", err)endlocal res, err = conn:request_uri("http://sse:3000/ssev2")if not res thenngx.say("failed to request: ", err)returnendwhile truedolocal event, err = conn:receive()if err thenngx.say(err)endif event thenngx.say(cjson.encode(event))endngx.flush(true)end}}}}运行
nodejs 基于了ncc,整体基于docker-compose
openresty
FROM openresty/openresty:1.21.4.1-0-alpine-fatRUN apk add --no-cache git && /usr/local/openresty/luajit/bin/luarocks install lua-resty-ssenode
FROM node:14.19.3-slimCOPY app/index.js /app/index.jsCMD [ "node","/app/index.js" ]docker-compose
version: '3'services:sse:build:context: ./dockerfile: Dockerfile-nodeports:- 3000:3000app:build: ./ports:- "80:80"volumes:- "./app/:/opt/app"- "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf"运行效果
- 默认

- 包含token的

说明
以上是一个简单的测试,可以参考使用
参考资料
https://github.com/openresty/lua-nginx-module
https://github.com/wojons/lua-resty-sse
https://github.com/rongfengliang/openresty-sse-proxy










