Skip to content

Instantly share code, notes, and snippets.

@snower
Created December 28, 2021 09:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snower/8ad4c30b56e2ae4eede0b37b20fb1bd3 to your computer and use it in GitHub Desktop.
Save snower/8ad4c30b56e2ae4eede0b37b20fb1bd3 to your computer and use it in GitHub Desktop.
openresty long polling server
init_worker_by_lua_block {
local slock = require "slock"
slock:connect("server1", "127.0.0.1", 5658)
}
server {
listen 8081;
default_type application/json;
location /poll/event {
content_by_lua_block {
local cjson = require "cjson"
local slock = require "slock"
local default_type = ngx.var.arg_default_type or "clear"
local wait_type = ngx.var.arg_wait_type or ""
local event_key = ngx.var.arg_event or ""
local wait_timeout = tonumber(ngx.var.arg_timeout) or 60
local sendResult = function(err_code, err_message)
ngx.say(cjson.encode({
err_code = err_code,
err_message = err_message,
}))
end
if event_key == "" then
return sendResult(400, "event key is empty")
end
local slock_client = slock:get("server1")
local event = nil
if default_type == "set" then
event = slock_client:newDefaultSetEvent(event_key, 5, wait_timeout * 2)
else
event = slock_client:newDefaultClearEvent(event_key, 5, wait_timeout * 2)
end
if wait_type == "reset" then
local ok, err = event:waitAndTimeoutRetryClear(wait_timeout)
if not ok then
return sendResult(504, "wait event timeout")
end
return sendResult(0, "succed")
end
local ok, err = event:wait(wait_timeout)
if not ok then
return sendResult(504, "wait event timeout")
end
return sendResult(0, "succed")
}
}
location /poll/message {
content_by_lua_block {
local cjson = require "cjson"
local redis = require "resty.redis"
local slock = require "slock"
local default_type = ngx.var.arg_default_type or "clear"
local wait_type = ngx.var.arg_wait_type or ""
local event_key = ngx.var.arg_event or ""
local wait_timeout = tonumber(ngx.var.arg_timeout) or 60
local sendResult = function(err_code, err_message, data)
ngx.say(cjson.encode({
err_code = err_code,
err_message = err_message,
data = data,
}))
end
if event_key == "" then
return sendResult(400, "event key is empty")
end
local redis_client = redis:new()
redis_client:set_timeouts(5000, wait_timeout * 500, wait_timeout * 500)
local ok, err = redis_client:connect("10.10.10.251", 6379)
if not ok then
return sendResult(502, "redis connect fail")
end
local message, err = redis_client:lpop(event_key)
if err ~= nil then
return sendResult(500, "redis lpop fail")
end
redis_client:set_keepalive(7200000, 16)
if message ~= ngx.null then
return sendResult(0, "", message)
end
local slock_client = slock:get("server1")
local event = nil
if default_type == "set" then
event = slock_client:newDefaultSetEvent(event_key, 5, wait_timeout * 2)
else
event = slock_client:newDefaultClearEvent(event_key, 5, wait_timeout * 2)
end
if wait_type == "reset" then
local ok, err = event:waitAndTimeoutRetryClear(wait_timeout)
if not ok then
return sendResult(504, "wait timeout")
end
redis_client = redis:new()
redis_client:set_timeouts(5000, wait_timeout * 500, wait_timeout * 500)
local ok, err = redis_client:connect("10.10.10.251", 6379)
if not ok then
return sendResult(502, "redis connect fail")
end
local message, err = redis_client:lpop(event_key)
if err ~= nil then
return sendResult(500, "redis lpop fail")
end
redis_client:set_keepalive(7200000, 16)
return sendResult(0, "succed", message)
end
local ok, err = event:wait(wait_timeout)
if not ok then
return sendResult(504, "wait timeout")
end
redis_client = redis:new()
redis_client:set_timeouts(5000, wait_timeout * 500, wait_timeout * 500)
local ok, err = redis_client:connect("10.10.10.251", 6379)
if not ok then
return sendResult(502, "redis connect fail")
end
local message, err = redis_client:lpop(event_key)
if err ~= nil then
return sendResult(500, "redis lpop fail")
end
redis_client:set_keepalive(7200000, 16)
return sendResult(0, "succed", message)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment