WebSockets with OpenResty

WebSockets with OpenResty

Lua WebSocket Implementation Installation
This blog post is updated for OpenResty


I have been following OpenResty development closely for a while now, but I did never got an inspiration to really try it out, until now. Yichun Zhang (@agentzh) of OpenResty-fame announced that he just released a preliminary WebSockets support for Lua Nginx module (lua-nginx-module). I have been waiting for this to happen.

I managed to install, and test this on my Mac. Here is how I did it:

$ brew install pcre
$ wget http://openresty.org/download/ngx_openresty-
$ tar zxf ngx_openresty-
$ cd ngx_openresty-
$ ./configure \
    --with-luajit \
    --with-cc-opt="-I/usr/local/Cellar/pcre/8.33/include" \
$ make
$ make install

Now we should have OpenResty installed with Lua module that supports WebSockets at /usr/local/openresty. Next we need to write the WebSockets server code (right now just a stupid echoing server). Again, edit nginx.conf, and add a new location after “location / { … }”:

location /s {
  lua_socket_log_errors off;
  lua_check_client_abort on;
  content_by_lua '
    local server = require "resty.websocket.server"
    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 ngx.exit(444)
    while true do
      local data, typ, err = wb:recv_frame()
      if wb.fatal then
        ngx.log(ngx.ERR, "failed to receive frame: ", err)
        return ngx.exit(444)
      if not data then
        local bytes, err = wb:send_ping()
        if not bytes then
          ngx.log(ngx.ERR, "failed to send ping: ", err)
          return ngx.exit(444)
      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 ngx.exit(444)
      elseif typ == "pong" then
        ngx.log(ngx.INFO, "client ponged")
      elseif typ == "text" then
        local bytes, err = wb:send_text(data)
        if not bytes then
          ngx.log(ngx.ERR, "failed to send text: ", err)
          return ngx.exit(444)

Looks great. Now add websockets.html to /usr/local/openresty/nginx/html directory:

var ws = null;
function connect() {
  if (ws !== null) return log('already connected');
  ws = new WebSocket('ws://');
  ws.onopen = function () {
  ws.onerror = function (error) {
  ws.onmessage = function (e) {
    log('recv: ' + e.data);
  ws.onclose = function () {
    ws = null;
  return false;
function disconnect() {
  if (ws === null) return log('already disconnected');
  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);
  return false;
function log(text) {
  var li = document.createElement('li');
  return false;
  <form onsubmit="return send();">
    <button type="button" onclick="return connect();">
    <button type="button" onclick="return disconnect();">
    <input id="text" type="text">
    <button type="submit">Send</button>
  <ol id="log"></ol>

And now start the nginx with:

sudo /usr/local/openresty/nginx/sbin/nginx

Then open a browser that has WebSocket support enabled, and open following url:

Lua Web Sockets in Action To guard against half-open TCP connections, it is a good idea to enable TCP keepalive in your Nginx listen configuration directive:

so_keepalive=on off [keepidle]:[keepintvl]:[keepcnt]];

for example:

listen 80 so_keepalive=2s:2s:8; (nginx documentation about so_keepalive) You could also do this on system level, if you wish:

$ sysctl net.inet.tcp.always_keepalive

net.inet.tcp.always_keepalive: 0

$ sudo sysctl -w net.inet.tcp.always_keepalive=1

net.inet.tcp.always_keepalive: 0 -> 1 (for Linux, see: Using TCP keepalive under Linux)

编辑:糖果 作者:Aapo Talvensaari



Apache APISIX在SAE应用市场发布

Apache APISIX在SAE应用市场发布 Continue reading


Published on December 06, 2019

Openresty Nginx Tengine添加动态so库

Published on October 11, 2019