openresty proxy sse 服务
作者:互联网
实际上如果单纯的进行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()` funciton
let 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 then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
// 内容处理,基于了sse client
content_by_lua_block {
local sse = require "resty.sse"
local cjson = require "cjson"
local conn, err = sse.new()
if not conn then
ngx.say("failed to get connection: ", err)
end
local res, err = conn:request_uri("http://sse:3000/ssev2")
if not res then
ngx.say("failed to request: ", err)
return
end
while true
do
local event, err = conn:receive()
if err then
ngx.say(err)
end
if event then
ngx.say(cjson.encode(event))
end
ngx.flush(true)
end
}
}
}
}
运行
nodejs 基于了ncc,整体基于docker-compose
openresty
FROM openresty/openresty:1.21.4.1-0-alpine-fat
RUN apk add --no-cache git && /usr/local/openresty/luajit/bin/luarocks install lua-resty-sse
node
FROM node:14.19.3-slim
COPY app/index.js /app/index.js
CMD [ "node","/app/index.js" ]
docker-compose
version: '3'
services:
sse:
build:
context: ./
dockerfile: Dockerfile-node
ports:
- 3000:3000
app:
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
标签:app,lua,proxy,openresty,sse,local 来源: https://www.cnblogs.com/rongfengliang/p/16328951.html