Hello,
I'm trying to implement simple json file output with lua-resty-websocket
module. Here is the example snippets of nginx and lua:
nginx ws-test.conf:
--------------------------------------------------------------------
server {
listen 3001 so_keepalive=5s:5s:10 backlog=65535;
server_name ws-test;
send_timeout 10s;
location / {
access_log /var/log/nginx/ws-access.log;
lua_socket_log_errors off;
lua_check_client_abort on;
content_by_lua_file /etc/nginx/lua/index.lua;
}
location /json {
internal;
root /var/www/;
}
}
--------------------------------------------------------------------
index.lua:
--------------------------------------------------------------------
local S = {}
S = {
['test'] = '1.json'
}
local server = require "resty.websocket.server"
-- websocket server
local ws, err = server:new{
timeout = 10000,
max_payload_len = 65535,
}
if not ws then
ngx.log(ngx.ERR, "failed to new websocket: ", err)
return ngx.exit(444)
end
while true do
local data, typ, err = ws:recv_frame()
if ws.fatal then
ngx.log(ngx.ERR, "failed to receive frame: ", err)
return ngx.exit(444)
end
if not data then
local bytes, err = ws:send_ping()
if not bytes then
ngx.log(ngx.ERR, "failed to send ping: ", err)
return ngx.exit(444)
end
elseif typ == "close" then break
elseif typ == "ping" then
local bytes, err = ws:send_pong()
if not bytes then
ngx.log(ngx.ERR, "failed to send pong: ", err)
return ngx.exit(444)
end
elseif typ == "pong" then
ngx.log(ngx.INFO, "client ponged")
-- send corresponding station metadata
elseif typ == "text" then
if data and S[data] ~= nil then
local res = ngx.location.capture("/json/"..S[data])
if res then
local bytes, err = ws:send_text(res.body)
if not bytes then
ngx.log(ngx.ERR, "failed to send metadata: ", err)
return ngx.exit(444)
end
end
end
end
end
ws:send_close()
--------------------------------------------------------------------
It works well but there is one problem. Each time message "test" is sent
through established websocke connection new file descriptor
/var/www/json/1.json is added while old descriptors remain open in nginx
worker. For example I test it with 'wscat --connect' and send "test"
message 5 times in one long connection. Then I get the following
descriptors in nginx worker:
nginx 12950 www-data 25r REG 252,1 2035
81396539 /var/www/xmlsource/json/3.json
nginx 12950 www-data 28r REG 252,1 2035
81396539 /var/www/xmlsource/json/3.json
nginx 12950 www-data 29r REG 252,1 2035
81396539 /var/www/xmlsource/json/3.json
nginx 12950 www-data 30r REG 252,1 2035
81396539 /var/www/xmlsource/json/3.json
nginx 12950 www-data 31r REG 252,1 2035
81396539 /var/www/xmlsource/json/3.json
I guess it happens because nginx connection still remains open (as
websocket in "keep-alive" mode with 'while true' loop).
So the main question here is there a way to properly handle this
situation and do not produce so many open files?
Best regards, Andrey