nginx push_upstream模块的websocket

参考

https://www.rails365.net/articles/websocket-wai-pian-nginx-push-stream-module-mo

安装

gitclonehttps://github.com/wandenberg/nginx-push-stream-module

./configure--add-module=/Users/haoning/tool/nginx/nginx-push-stream-module--prefix=/usr/local/nginx_push_stream

make

makeinstall

nginx配置加入

push_stream_shared_memory_size 32M;
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

		location /channels-stats {
            # activate channels statistics mode for this location
            push_stream_channels_statistics;

            # query string based channel id
            push_stream_channels_path               $arg_id;
        }

        location /pub {
            # activate publisher (admin) mode for this location
            push_stream_publisher admin;

            # query string based channel id
            push_stream_channels_path               $arg_id;
        }

        location ~ /ws/(.*) {
            # activate websocket mode for this location
            push_stream_subscriber websocket;

            # positional channel path
            push_stream_channels_path                   $1;
            # message template
            push_stream_message_template                "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":\"~text~\"}";

            push_stream_websocket_allow_publish         on;

            # ping frequency
            push_stream_ping_message_interval           10s;
        }

启动nginx

测试查看状态

curl-s-v'http://localhost/channels-stats'

测试写入

curlhttp://localhost/pub\?id\=ch1-d"SomeText"{"channel":"ch1","published_messages":1,"stored_messages":0,"subscribers":1}

h5的客户端代码

<html>
<head>
<script>
var ws = null;
function connect() {
  if (ws !== null) return log('already connected');
  ws = new WebSocket('ws://localhost/ws/ch1');
  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>
  {"name": "Bruce.Lin", "age": 25}
  <form onsubmit="return send();">
    <button type="button" onclick="return connect();">
      Connect
    </button>
    <button type="button" onclick="return disconnect();">
      Disconnect
    </button>
    <input id="text" type="text">
    <button type="submit">Send</button>
  </form>
  <ol id="log"></ol>
</body>
</html>

ruby的客户端代码

require 'net/http'

uri = URI("http://localhost/pub\?id\=ch1")
http = Net::HTTP.new(uri.host, uri.port)

req = Net::HTTP::Post.new(uri.to_s)
req.body = 'Some Text'

http.request(req)