魏长东

weichangdong

nginx-push-stream-module 使用

安装完成之后,实现了我一直以来想实现的效果。浏览器上显示了推送的消息。不是浏览器主动请求触发的。

大体流程这样的,现在浏览器上访问一个地址,然后这个请求应该是一直没断。然后我在服务器发送一条消息,浏览器就显示了这条消息。好神奇啊,有木有~~~~

web-push.png

下面给出安装的过程

按照这个步骤安装https://github.com/wandenberg/nginx-push-stream-module#installation

执行这个命令(在linux服务器)

curl -s -v --no-buffer 'http://localhost/sub/my_channel_1'

然后浏览器访问http://192.168.150.128/sub/my_channel_1 (我的虚拟机地址)

然后服务器执行命令

curl -s -v -X POST 'http://localhost/pub?id=my_channel_1' -d 'Hello World!'

浏览器就会弹出hello world、

附上nginx配置文件

pid         logs/nginx.pid;
error_log   logs/nginx-main_error.log debug;

# Development Mode
master_process      off;
daemon              off;
worker_rlimit_core  2500M;
working_directory /tmp;
debug_points abort;
env MOCKEAGAIN_VERBOSE;
env MOCKEAGAIN_WRITE_TIMEOUT_PATTERN;
#env MOCKEAGAIN;
env LD_PRELOAD;

worker_processes    2;

events {
    worker_connections  1024;
#    use                 poll;
}

http {
    postpone_output 1; # only postpone a single byte, default 1460 bytes
    access_log      logs/nginx-http_access.log;

    push_stream_shared_memory_size                100m;
    push_stream_max_channel_id_length             200;
    # max messages to store in memory
    push_stream_max_messages_stored_per_channel   20;
    # message ttl
    push_stream_message_ttl                       5m;
    # ping frequency
    push_stream_ping_message_interval             30s;
    # connection ttl to enable recycle
    push_stream_subscriber_connection_ttl         15m;
    # connection ttl for long polling
    push_stream_longpolling_connection_ttl        30s;
    push_stream_timeout_with_body                 off;

    # wildcard
    push_stream_wildcard_channel_prefix         "broad_";
    push_stream_wildcard_channel_max_qtd        3;

    push_stream_message_template                "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":\"~text~\", \"tag\":\"~tag~\", \"time\":\"~time~\", \"eventid\":\"~event-id~\"}";

    # subscriber may create channels on demand or only authorized (publisher) may do it?
    push_stream_authorized_channels_only        off;

    push_stream_allowed_origins                 "*";

    server {
        listen           80 default_server;
        #listen          9443 ssl;
        #ssl_certificate     /usr/local/nginx/ssl/server.crt;
        #ssl_certificate_key /usr/local/nginx/ssl/server.key;
        server_name     localhost;

        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 mode for this location, with admin support
            push_stream_publisher admin;

            # query string based channel id
            push_stream_channels_path               $arg_id;

            # store messages in memory
            push_stream_store_messages              on;

            # Message size limit
            # client_max_body_size MUST be equal to client_body_buffer_size or
            # you will be sorry.
            client_max_body_size                    32k;
            client_body_buffer_size                 32k;
        }

        location ~ /sub/(.*) {
            # activate subscriber mode for this location
            push_stream_subscriber;

            # positional channel path
            push_stream_channels_path                   $1;
            if ($arg_tests = "on") {
              push_stream_channels_path                 "test_$1";
            }

            # header to be sent when receiving new subscriber connection
            push_stream_header_template                 "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n<meta http-equiv=\"Cache-Control\" content=\"no-store\">\r\n<meta http-equiv=\"Cache-Control\" content=\"no-cache\">\r\n<meta http-equiv=\"Pragma\" content=\"no-cache\">\r\n<meta http-equiv=\"Expires\" content=\"Thu, 1 Jan 1970 00:00:00 GMT\">\r\n<script type=\"text/javascript\">\r\nwindow.onError = null;\r\ntry{ document.domain = (window.location.hostname.match(/^(\d{1,3}\.){3}\d{1,3}$/)) ? window.location.hostname : window.location.hostname.split('.').slice(-1 * Math.max(window.location.hostname.split('.').length - 1, (window.location.hostname.match(/(\w{4,}\.\w{2}|\.\w{3,})$/) ? 2 : 3))).join('.');}catch(e){}\r\nparent.PushStream.register(this);\r\n</script>\r\n</head>\r\n<body>";

            # message template
            #push_stream_message_template                "<script>p(~id~,'~channel~','~text~','~event-id~', '~time~', '~tag~');</script>";
            push_stream_message_template                "<script>alert('~text~');</script>";#edit by wcd
            # footer to be sent when finishing subscriber connection
            push_stream_footer_template                 "</body></html>";
            # content-type
            default_type                                "text/html; charset=utf-8";

            if ($arg_qs = "on") {
              push_stream_last_received_message_time "$arg_time";
              push_stream_last_received_message_tag  "$arg_tag";
              push_stream_last_event_id              "$arg_eventid";
            }
        }

        location ~ /ev/(.*) {
            # activate event source mode for this location
            push_stream_subscriber eventsource;

            # positional channel path
            push_stream_channels_path                   $1;
            if ($arg_tests = "on") {
              push_stream_channels_path                 "test_$1";
            }

            if ($arg_qs = "on") {
              push_stream_last_received_message_time "$arg_time";
              push_stream_last_received_message_tag  "$arg_tag";
              push_stream_last_event_id              "$arg_eventid";
            }
        }

        location ~ /lp/(.*) {
            # activate long-polling mode for this location
            push_stream_subscriber      long-polling;

            # positional channel path
            push_stream_channels_path         $1;
            if ($arg_tests = "on") {
              push_stream_channels_path                 "test_$1";
            }

            if ($arg_qs = "on") {
              push_stream_last_received_message_time "$arg_time";
              push_stream_last_received_message_tag  "$arg_tag";
              push_stream_last_event_id              "$arg_eventid";
            }
        }

        location ~ /jsonp/(.*) {
            # activate long-polling mode for this location
            push_stream_subscriber      long-polling;

            push_stream_last_received_message_time "$arg_time";
            push_stream_last_received_message_tag  "$arg_tag";
            push_stream_last_event_id              "$arg_eventid";

            # positional channel path
            push_stream_channels_path         $1;
            if ($arg_tests = "on") {
              push_stream_channels_path                 "test_$1";
            }
        }

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

            # positional channel path
            push_stream_channels_path                   $1;
            if ($arg_tests = "on") {
              push_stream_channels_path                 "test_$1";
            }

            # store messages in memory
            push_stream_store_messages              on;

            push_stream_websocket_allow_publish     on;

            if ($arg_qs = "on") {
              push_stream_last_received_message_time "$arg_time";
              push_stream_last_received_message_tag  "$arg_tag";
              push_stream_last_event_id              "$arg_eventid";
            }
        }

        location / {
            if (!-f $request_filename) {
              proxy_pass "http://localhost:8888";
            }
        }
    }
}

最基本的实现了,别的高级的就不研究了,将来要是实际开发用到了,在继续研究。