wandenberg / nginx-push-stream-module

A pure stream http push technology for your Nginx setup. Comet made easy and really scalable.
Other
2.22k stars 295 forks source link

Sockets on 3G #225

Closed clayrain closed 8 years ago

clayrain commented 8 years ago

Using Nginx version 1.9.9

Trying to figure out why the websocket example drops on 3G to "offline status" after trying to type in a field. Works fine on desktop. However, the example at http://www.nginxpushstream.com/chat.html does work consistently on the phone:

Could it be the nginx.conf file has a difference???????

This is my current config:

user www-data; worker_processes 1;

events { worker_connections 1024; }

http { include mime.types; default_type application/octet-stream;

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

push_stream_shared_memory_size                32m;
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             10s;
# 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                 "*";

sendfile        on;
keepalive_timeout  65;

server {
    listen       80;
    server_name localhost;

    location / {
        root  /var/www/kickriot/html;
        index index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /var/www/kickriot/html;
    }

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>";
        # 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 ~ /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 /local_redirect {
        rewrite ^.*$ newname? permanent;
    }

}

server {
    listen       8080;
    server_name  localhost;
    location /control {
        rtmp_control all;
    }
 }

}

wandenberg commented 8 years ago

Sorry, I didn't understand your problem. Are you running the example chat application and it is not working? Try to use one of the examples that are on docs with simpler configurations/html before move to a more advanced scenario with rtmp and so on. I don't believe that 3G should change the behavior of your application.

clayrain commented 8 years ago

Hi, not a newbie with the rest, only with this module.

I learned by setting the push_stream_ping_message_interval to 5 seconds the connection does not drop on a 3G network (at least the one I am using) on an iPhone. But it would be nice not to have to ping every 5 seconds only because of the 3G network issue. And maybe this isn't the real cure but only a happenstance patch.

In general it seems this issue is related to websockets on 3G, and not this module:

http://stackoverflow.com/questions/5557776/websockets-over-a-3g-connection

To reproduce, I have had installed a bare bones from the example, then on an iPhone, on a 3G network (not wifi), when focus is brought to the the nickname form then to the message field to type a message, the status of page goes to OFF LINE (red words).

I notice though the one of the live demo on the server, for the most part, does not have the same issue. Which brings up the following questions to try to understand how come the demo server works predictably on 3G?

The question is in two parts:

  1. is the config file different than what is included in the example? The example demo at: http://www.nginxpushstream.com/chat.html is what is being referred to. Since this seems to work on 3G on an iPhone.
  2. If it is the same nginx.config as given in the example on git, then the question would be: is there anything else that differs from the example git that would make the version at http://www.nginxpushstream.com/chat.html stay alive on a 3G iPhone connection vs the git version that I installed?

It could be a difference in servers if I would have to blindly start guessing at variables, but I like the scientific approach better than guess :)

Any insight would be greatly appreciated to understand what is different at http://www.nginxpushstream.com/chat.html vs what I have running.

Maybe it is the rtmp block and the rest of the stuff going on in the config file and my server with only 512MB memory that is causing an issue. Don't know. Hoping to get some more facts to further investigate.

Since by changing to 5 seconds yielded a positive result, want to understand better if this is the true solution or if other variables could be effecting the connection on 3G.

Let me know if there is anything I can write or provide to better clarify. Thank you very much for your insight..

wandenberg commented 8 years ago

Hi @clayrain

the live demo application set a push_stream_ping_message_interval of 10 seconds. It's possible that the mobile closes the connection if there is no traffic for optimizations issues, battery as example. Once you set the ping message will always have traffic. The configuration at live demo is something like this

    push_stream_shared_memory_size     20M;
    push_stream_max_messages_stored_per_channel 20;
    push_stream_message_ttl                     20m;
    push_stream_authorized_channels_only        off;
    push_stream_ping_message_interval           10s;
    push_stream_subscriber_connection_ttl       15m;
    push_stream_longpolling_connection_ttl      30s;
    push_stream_broadcast_channel_prefix        "broad_";
    push_stream_broadcast_channel_max_qtd       3;
    push_stream_message_template                "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":\"~text~\"}";

What I mean about using a simpler configuration is that the file at 'misc' folder has a lot of conditionals and extra configurations because I use it for development, and it must not be used on production as is.

To sum up, probably your issue can be solved in two ways, set the ping message interval like you did using a reasonable time, like 10 or 15 seconds, or use long polling while on 3G. But I don't know if you will have access to this information from the browser API.