本文主要介绍nginx配合lua构建websocket 例子。
下载lua-resty-websocket
git clone https://github.com/agentzh/lua-resty-websocket.git
nginx conf 配置
server {
listen 38000;
server_name localhost;
lua_code_cache off;
location /webs {
content_by_lua_file '/home/cq/share/sss/nginx_example/websocket.lua';
}
location / {
root html;
index index.html index.htm;
}
}
lua 代码
package.path = "/home/cq/nginx/lua/lua-resty-websocket/lib/?.lua;"
--local server = require "lua-resty-websocket.lib.resty.websocket.server"
local server = require "resty.websocket.server"
local wb, err = server:new{
timeout = 15000,
max_payload_len = 65535,
}
if not wb then
ngx.log(ngx.ERR, "failed to new websocket: ", err)
return ngx.exit(444)
end
local data, typ, err = wb:recv_frame()
if not data then
ngx.log(ngx.ERR, "failed to receive a frame: ", err)
return ngx.exit(444)
end
if typ == "close" then
--send a close frame back:
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send close frame: ", err)
return
end
local code = err
ngx.log(ngx.INFO, "closing with status code", code, " and message ", data)
return
end
if typ == "ping" then
--send a pong frame back:
local bytes, err = wb:send_pong(data)
if not bytes then
ngx.log(ngx.ERR, "failed to semd frame: ", err)
return
end
elseif typ == "pong" then
-- just discard the incoming pong frame
else
ngx.log(ngx.INFO, "receive a frame of type ", typ, " and payload ", data)
end
wb:set_timeout(1000) --change the network timeout to 1 second
bytes, err = wb:send_text("hello world")
if not bytes then
ngx.log(ngx.ERR, "failed to send a text frame: ", err)
return ngx.exit(444)
end
bytes, err = wb:send_binary("blah blah blah..")
if not bytes then
ngx.log(ngx.ERR, "failed to send binary frame: ", err)
return ngx.exit(444)
end
bytes, err = wb:send_text(data)
if not bytes then
ngx.log(ngx.ERR, "failed to send data frame: ", err)
return ngx.exit(444)
end
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send the close frame: ", err)
return
end
测试的html代码:
<html>
<head>
<script>
var ws = null;
function connect() {
if (ws !== null) return log('already connected');
ws = new WebSocket('ws://192.168.0.248:38000/webs');
ws.onopen = function () {
log('connected');
};
ws.onerror = function (error) {
log(error);
};
ws.onmessage = function (e) {
log('recv: ' + e.data);
};
ws.onclose = function () {
log('disconnected');
ws = null;
};
return false;
}
function disconnect() {
if (ws === null) return log('already disconnected');
ws.close();
return false;
}
function send() {
if (ws === null) return log('please connect first');
var text = document.getElementById('text').value;
document.getElementById('text').value = "";
log('send: ' + text);
ws.send(text);
return false;
}
function log(text) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(text));
document.getElementById('log').appendChild(li);
return false;
}
</script>
</head>
<body>
<form οnsubmit="return send();">
<button type="button" οnclick="return connect();">
Connect
</button>
<button type="button" οnclick="return disconnect();">
Disconnect
</button>
<input id="text" type="text">
<button type="submit">Send</button>
</form>
<ol id="log"></ol>
</body>
</html>
重载nginx
测试结果: