nchan icon indicating copy to clipboard operation
nchan copied to clipboard

nchan_publisher_upstream_request seems not to work fine with websocket

Open zja711 opened this issue 7 years ago • 2 comments

nginx version: nginx/1.13.8

server {
    listen 8402 default_server;
    access_log  /var/log/nginx/pubsub.access.log;
    error_log  /var/log/nginx/pubsub.error.log debug;

    location = /sub {
      nchan_subscriber;
      nchan_channel_id $arg_id;
    }

    location = /pubsub {  
        nchan_pubsub;
        nchan_channel_id $arg_id;
        nchan_publisher_upstream_request /upstream_pub;
    }
    

    location = /upstream_pub {
        proxy_pass http://127.0.0.1:8402/test;
        
        proxy_set_header X-Publisher-Type $nchan_publisher_type;
        proxy_set_header X-Prev-Message-Id $nchan_prev_message_id;
        proxy_set_header X-Channel-Id $nchan_channel_id;
        proxy_set_header X-Original-URI $request_uri;
    }

    location /test {
        default_type text/html;
        return 200 "test........";
    }
}


client side:

ws = new WebSocket("ws://192.168.0.200:8402/pubsub?id=1");
ws.onmessage = function(evt){console.log(evt.data);};

curl --request POST --data "http 1" http://192.168.0.200:8402/pub?id=1 output:test........

curl --request POST --data "http 2" http://192.168.0.200:8402/pub?id=1 output:test........

ws.send("aaa") // it seems that nginx don't work fine whenever send data,then i should reload output:test........

curl --request POST --data "http 3" http://192.168.0.200:8402/pub?id=1 request hangs receive nothing

or

ws.send("aaa") receive nothing

zja711 avatar Jan 11 '18 09:01 zja711

This should be fixed in Nchan version 1.2.0

slact avatar Jul 25 '18 08:07 slact

Currently I'm facing something quite similar in nchan version: 1.2.7. I'm using django+gunicorn(wsgi) as the backend. I'm making a simple chat app, with "box" as a container with multiple "channels" that can be accessed by users (aka "personalities")

upstream redis_server { nchan_redis_server redis://127.0.0.1/0; }
nchan_redis_pass redis_server;

server {

	location ~ ^/box/(\w+)$ {
		proxy_pass http://gunicorn_wsgi/api/box_connect/$1; //Uses accel-redirect to authenticate and connect to an internal pubsub 
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}

	nchan_channel_group_accounting on;

	location ~ ^/pubsub/b/(\d+)/c/(\d+)/p/(\d+)$ { # box_id / channel_id / personality_id
		internal;
		nchan_pubsub;
		nchan_channel_group $1; #Group Boxes together

		nchan_websocket_client_heartbeat PING PONG;
		nchan_websocket_ping_interval 30;
		nchan_publisher_upstream_request /upstream_pub; //If I comment this line, everything will be stable! (I just won't get new messages )

		nchan_publisher_channel_id  C$2P$3O;        #Personal Publisher, Upstream should discard!
		nchan_subscriber_channel_id C$2 C$2P$3;  #Subscribe to public and Private Channel
	}

	location = /upstream_pub {
		internal;

		proxy_pass http://gunicorn_wsgi/api/new_message;
		proxy_set_header Host $host;
		proxy_set_header X-Publisher-Type $nchan_publisher_type;
		proxy_set_header X-Prev-Message-Id $nchan_prev_message_id;
		proxy_set_header X-Channel-Id $nchan_channel_id;
		proxy_set_header X-Original-URI $request_uri;
	}
}

server {
	listen 127.0.0.1:8080;

	location ~ ^/pub/b/(\d+)/c/(\d+)/p/(\d+)$ {
		nchan_message_buffer_length 0;
		nchan_message_timeout 1s;
		nchan_publisher;
		nchan_channel_id   C$2P$3;
		nchan_channel_group $1;
	}

	location ~ ^/pub/b/(\d+)/c/(\d+)$ {
		nchan_message_buffer_length 1;
		nchan_message_timeout 5s;
		nchan_publisher;
		nchan_channel_id   C$2;
		nchan_channel_group $1;
	}
}

And this is the relevant part of django:

def box_connect( request, box_uid ):
        ... #Authentication takes place here...

	response = HttpResponse()
	response['X-Accel-Redirect']  = f'/pubsub/b/{channel.box_id}/c/{channel.id}/p/{personality.id}'
	response['X-Accel-Buffering'] = 'no'
	return response

And what happens, is that after like the first couple of successful publishes, no more messages can be published and the POST request will get stuck!

curl --request POST --data 'A Publish Message to all channel members' -H "Accept: text/json" "http://127.0.0.1:8080/pub/b/2/c/3"

a nginx reload / restart will fix the issue for about 2 seconds! my current "workaround" is to use a single channel for all users to publish to, and somehow identify them from their message.

aliqandil avatar Jan 23 '21 23:01 aliqandil