11 Star 30 Fork 6

poempro/openresty-websocket

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
websocket.lua 3.86 KB
一键复制 编辑 原始数据 按行查看 历史
poempro 提交于 2017-06-14 14:14 . 更新 websocket.lua
--[[
- @desc 用于调试 lua数据输出
- @param string 字符串
- return string
--]]
function dump(v)
if not __dump then
function __dump(v, t, p)
local k = p or "";
if type(v) ~= "table" then
table.insert(t, k .. " : " .. tostring(v));
else
for key, value in pairs(v) do
__dump(value, t, k .. "[" .. key .. "]");
end
end
end
end
local t = {'======== Lib:Dump Content ========'};
__dump(v, t);
print(table.concat(t, "\n"));
end
local server = require "resty.websocket.server"
local redis = require "resty.redis"
local cjson = require "cjson"
local function exit()
--获取URL参数
local _GET = ngx.req.get_uri_args()
ngx.log(ngx.ERR, "用户" .. _GET['rnd'] .." 离开了房间 : ", err)
--if is_ws == nil then ngx.eof() end
ngx.flush(true)
ngx.exit(ngx.HTTP_OK)
return nil
end
local ok, err = ngx.on_abort(exit) --注册一个函数 当客户端断开连接时执行
if err then
return exit()
end
--获取聊天室id
local channel_id = 800
local channel_name = "chat_" .. tostring(channel_id)
--create connection
local wb, err = server:new{
timeout = 5000,
max_payload_len = 65535
}
if not wb then
ngx.log(ngx.ERR, "failed to new websocket: ", err)
return exit()
end
----创建redis实例
local getRedis = function (key)
if not key then
return nil
end
if ngx.ctx[key] then
return ngx.ctx[key]
end
--dump('-------------创建redis实例---------------------')
local red = redis:new()
--red:set_timeout(5000) -- 1 sec 设置连接超时1秒
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect redis: ", err)
end
ngx.ctx[key] = red
return red
end
local pub = function()
local red = getRedis('redisfn1')
--redis 订阅
local res, err = red:subscribe(channel_name)
if not res then
ngx.log(ngx.ERR, "failed to sub redis: ", err)
wb:send_close()
return exit()
end
-- 不断读取数据如果有值立刻发送给客户端
while true do
local res, err = red:read_reply()
if res then
local bytes, err = wb:send_text(cjson.encode(res))
if not bytes then
wb:send_close()
ngx.log(ngx.ERR, "failed to send text: ", err)
return exit()
end
end
ngx.sleep(0.5)
end
end
local co = ngx.thread.spawn(pub)
--main loop
while true do
-- 获取数据
local data, typ, err = wb:recv_frame()
-- 如果连接损坏 退出
if wb.fatal then
ngx.log(ngx.ERR, "failed to receive frame: ", err)
return exit()
end
if not data then
local bytes, err = wb:send_ping()
if not bytes then
ngx.log(ngx.ERR, "failed to send ping: ", err)
return exit()
end
elseif typ == "close" then
break
elseif typ == "ping" then
local bytes, err = wb:send_pong()
if not bytes then
ngx.log(ngx.ERR, "failed to send pong: ", err)
return exit()
end
elseif typ == "pong" then
--ngx.log(ngx.ERR, "client ponged")
elseif typ == "text" then
--接收消息写入redis
local red = getRedis('redisfn2')
local res, err = red:publish(channel_name, data)
if not res then
ngx.log(ngx.ERR, " 接收消息写入redis错误 failed to publish redis: ", err)
end
else
break
end
ngx.sleep(0.5)
end
getRedis('redisfn1'):set_keepalive(10000, 100)
getRedis('redisfn2'):set_keepalive(10000, 100)
wb:send_close()
ngx.thread.wait(co)
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Lua
1
https://gitee.com/sixiong/openresty-websocket.git
[email protected]:sixiong/openresty-websocket.git
sixiong
openresty-websocket
openresty-websocket
master

搜索帮助