我是靠谱客的博主 有魅力月饼,最近开发中收集的这篇文章主要介绍Nginx Lua OpenResty 反向代理websocket并对响应内容进行过滤,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【需求】

目前是有一个日志系统的Websocket接口持续不断输出日志,目前用户可以调用,但是Websocket Server发送的日志数据有一些比较细致对用户无用,我们需要过滤掉这些对用户无用的信息,让包含这些信息的data不发送给用户。

【前期尝试】

首先我知道nginx可以直接反向代理 websocket。
其次我也知道可以通过openresty中的body_filter_by_lua对响应进行处理。
那么将这两者结合起来能否实现websocket的消息过滤呢?
答案是不能。或者说可以实现但是非常复杂,涉及到一系列协议,因此放弃了。

【最终方案】

经过广泛搜集资料:发现了一个日本小哥写的Gists websocketをフックする
他使用了 lua-resty-websocket 这个库,通过一个桥连接非常优雅的实现了websocket上下游通讯。
通过对小哥的方案进行修改,非常完美的达到了自己的目的。

【lua-resty-websocket库】

https://github.com/openresty/lua-resty-websocket
大家先去lua-resty-websocket官网把websocket依赖下载下来放到自己的resty目录下。

【nginx.conf】

location = /ws_filter
{
	content_by_lua_file "ws_filter.lua";
}

【ws_filter.lua】

local server = require "resty/websocket/server"
local client = require "resty/websocket/client"
local protocol = require "resty/websocket/protocol"

-- websocket server
local sock_server, err = server:new()

if not sock_server then
    ngx.log(ngx.ERR, "failed to new websocket: ", err)
    return ngx.exit(403)
end

local sock_client, err = client:new()
-- 此处是代理的目标 ws 地址,可根据自己的需求进行重写等操作。
-- local uri = "ws://" ..  ngx.var.http_host ..  ngx.var.uri ..  ngx.var.is_args ..  ngx.var.args
local uri = "ws://www.myhost.com/api/websocket?pass=pass"
local ok, err = sock_client:connect(uri)

if not ok then
    ngx.log(ngx.ERR, "failed to connect remote: ", err)
    ngx.exit(403)
end

local function ws_proxy(sock_from, sock_to, flip_masking)
    local opcode_mapper = {
        ["continuation"] = 0x0,
        ["text"] = 0x1,
        ["binary"] = 0x2,
        ["close"] = 0x8,
        ["ping"] = 0x9,
        ["pong"] = 0x9,
    }

    while true do
        local data, typ, err = sock_from:recv_frame(flip_masking)

        if data == nil then
            -- socket already closed
            sock_to:send_close()
            break
        else
            ngx.log(ngx.INFO, data .. " (" .. typ .. ")")

            local fin = (typ ~= "continuation")

            if typ == "close" then
                sock_from:send_close()
            end
            
            -- 在这里对data进行处理
            -- data = 'filterdata'

            local bytes, err = sock_to:send_frame(fin, opcode_mapper[typ], data, flip_masking)

            if bytes == nil then
                sock_from:send_close()
                break
            end
        end

    end
end

local s2c = ngx.thread.spawn(ws_proxy, sock_client, sock_server, false)
local c2s = ngx.thread.spawn(ws_proxy, sock_server, sock_client, true)

if not ngx.thread.wait(s2c) then
    ngx.log(ngx.ERR, "s2c wait failed")
end

if not ngx.thread.wait(c2s) then
    ngx.log(ngx.ERR, "c2s wait failed")
end

最后

以上就是有魅力月饼为你收集整理的Nginx Lua OpenResty 反向代理websocket并对响应内容进行过滤的全部内容,希望文章能够帮你解决Nginx Lua OpenResty 反向代理websocket并对响应内容进行过滤所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部