slact / nchan.js Goto Github PK
View Code? Open in Web Editor NEWNPM package for the Javasript client for Nchan
License: Other
NPM package for the Javasript client for Nchan
License: Other
OK, not sure if it nchan or nchan.js problem, but here it goes:
We are trying to migrate from Faye, and while our chat mostly works fine with nchan, there are several issues. I will describe one as it seems like something you would be able to reproduce
The problem: when chat users are in the same browser process, just different tabs, repeated messages are ignored sometimes.
After I was reported of this, I tried to reproduce and changed out chat backend code to send the message 50 times instead of one.
If I use Chrome + Safari pair, everything works just fine - every time I send a message, I receive it in every browser 50 times.
If I use several Chrome tabs in incognito mode, everything works fine, too.
if I use two tabs in one Chrome window, this is what happens - the "broken" tab will receive the message sent just once, while the good tab will receive it 50 times.
What it a "broken" tab?
The backend injects several channel URLs for the frontend, like this
<script type="text/javascript">var nchanUrls = (nchanUrls || []).concat(['https://dev.company.com//sub/channel/2']);</script>
<script type="text/javascript">var nchanUrls = (nchanUrls || []).concat(['https://dev.company.com//sub/channel/2/private/2']);</script>
and then this simple script listens to messages
Pubsub = {
init: function () {
self = this;
self.online = false;
for (var i = 0; i < nchanUrls.length; i++ ) {
var nchanUrl = nchanUrls[i];
var sub = new NchanSubscriber(nchanUrl, { subscriber: ['websocket', 'longpoll'], shared: true });
sub.on('message', Pubsub.nchanMessage);
sub.on('connect', function(evt) {
self.online = true;
});
sub.on('disconnect', function(evt){
self.online = false;
});
sub.start();
}
},
nchanMessage: function(message, message_metadata) {
// message is a string
// message_metadata is a hash that may contain 'id' and 'content-type'
message = JSON.parse(message);
eval(message.data.eval);
}
}
So I call a "good" tab a tab that opens exactly the same number of WS connections as the number of URLs passed from the backend.
A "broken" tab will have less connections open than the number of URLs
Some screenshots:
this is a good tab:
this is a "broken" tab (it has only one connection open, but 2 URLs were passed from the backend):
Another observation - usually, it will always be the same - one tab is broken, another one is good. Not that it randomly both good, both broken, one good and another one broken.
If I enable the reconnect
feature, some times they will change sides (broken becomes good, and vice versa).
Same behaviour in both browser I've tested, Safari (9.1.3 (9537.86.7.8)
) and Chrome (59.0.3071.115
).
When creating a new NchanSubscriber with the shared option set to true, the connection takes upwards of 20 seconds to establish. Additionally, it appears to not connect at all in IE11. With the shared option undefined, the connection is established immediately and works fine in IE11. I don't think I'm doing anything unusual, but here's some boiled down example code just in case...
let subscription = new NchanSubscriber('/sub/test', {
subscriber: ['websocket', 'eventsource'],
reconnect: 'session',
shared: true //this is causing trouble. If left out, everything is fine.
});
subscription.on('connect', function(evt) {
console.log('connect');
//fired when first connected.
});
subscription.start();
Any idea what could be going on?
The hard-coded dependency on the window object throws errors when running this library in a browser worker where the Window is not defined. Specifically, line 81
"use strict";
function NchanSubscriber(url, opt) {
if(this === window) {
throw "use 'new NchanSubscriber(...)' to initialize";
}
I think a simple fix would be to check whether window exists first
if (typeof window !== 'undefined' && this === window)
My authentication requires a certain header. This seems to work fine with http but with websocket it's not inheriting the headerjar. In socket.io this seems to happen automatically. Is it advisable to use socket.io if we need custom headers? Would it be worth while to implement a socket.io subscriber type in order to get the headers?
By the way. Thank you!
I'm trying to debug strange connections issues and I don't know what step to take next.
Here is all the info I have right now:
overview: the app is a collaboration app, with one (or more) presenter and several viewers. Presenters and viewers are connected to nginx
with nchan
via websockets using NchanSubscriber
.
Presenters can send simple POST
requests to the Rails app, Rails will publish the events via nchan
to all connected viewers.
There are several server configs (servers listening on different domains with their own SSL certs), all of them have the same nchan
related nginx
config
client_max_body_size 128M;
location ~ /sub/(.*)$ {
nchan_subscriber;
nchan_channel_id $1;
#nchan_channel_group test;
nchan_channel_events_channel_id $1;
nchan_subscriber_first_message oldest;
nchan_subscribe_request /upstream/sub;
nchan_unsubscribe_request /upstream/unsub;
}
location = /upstream/unsub {
proxy_pass http://main_server/ws/unsub;
proxy_ignore_client_abort on; #!!!important!!!!
proxy_set_header X-Subscriber-Type $nchan_subscriber_type;
proxy_set_header X-Channel-Id $nchan_channel_id;
proxy_set_header X-Original-URI $request_uri;
}
location = /upstream/sub {
proxy_pass http://main_server/ws/sub;
proxy_set_header X-Subscriber-Type $nchan_subscriber_type;
proxy_set_header X-Message-Id $nchan_message_id;
proxy_set_header X-Channel-Id $nchan_channel_id;
proxy_set_header X-Original-URI $request_uri;
}
And there is a single pub
server, available only locally:
server {
listen 10.0.0.90:80;
server_name 10.0.0.90;
access_log /var/log/nginx/localhost.access.log;
location ~ /pub/(.*)$ {
nchan_publisher;
nchan_channel_id $1;
#nchan_channel_group test;
#nchan_channel_events_channel_id $1;
nchan_message_buffer_length 0;
nchan_message_timeout 30s;
}
location ~ /channel_events/(.*)$ {
#channel events subscriber location
nchan_subscriber;
nchan_channel_group meta; # "meta" is a SPECIAL channel group
nchan_channel_id $1;
}
location /nchan_stub_status {
nchan_stub_status;
}
location / {
root /var/www/nginx-default;
index index.html index.htm;
}
}
nginx -V
nginx version: nginx/1.10.1
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-stream --with-stream_ssl_module --add-module=/build/nginx/debian/modules/headers-more-nginx-module --add-module=/build/nginx/debian/modules/nginx-auth-pam --add-module=/build/nginx/debian/modules/nginx-cache-purge --add-module=/build/nginx/debian/modules/nginx-dav-ext-module --add-module=/build/nginx/debian/modules/nginx-development-kit --add-module=/build/nginx/debian/modules/nginx-echo --add-module=/build/nginx/debian/modules/ngx-fancyindex --add-module=/build/nginx/debian/modules/nchan --add-module=/build/nginx/debian/modules/nginx-lua --add-module=/build/nginx/debian/modules/nginx-upload-progress --add-module=/build/nginx/debian/modules/nginx-upstream-fair --add-module=/build/nginx/debian/modules/ngx_http_substitutions_filter_module
OK, to the problem itself.
Here are several logs from client side:
I, [2018-07-09T17:25:39.608787 #4071] INFO -- : PAGE: First event after page (re)load
I, [2018-07-09T17:25:39.608825 #4071] INFO -- : PAGE: Browser: Firefox 61.0 (Windows)
I, [2018-07-09T17:25:39.608877 #4071] INFO -- : PAGE: UA: Mozilla/5.0 (Windows NT 10.0; rv:61.0) Gecko/20100101 Firefox/61.0
I, [2018-07-09T17:25:39.608903 #4071] INFO -- : PAGE: Resolution: 1583x763
I, [2018-07-09T17:25:39.608925 #4071] INFO -- : PAGE: Resize, mw: 1100px, md: true, fs: false
I, [2018-07-09T17:25:39.608947 #4071] INFO -- : PAGE: Using NChan
I, [2018-07-09T17:25:39.608968 #4071] INFO -- : PUBSUB: Connected
I, [2018-07-09T17:25:39.608989 #4071] INFO -- : PUBSUB: Connected
and another example
I, [2018-07-09T17:28:14.835192 #25076] INFO -- : PAGE: First event after page (re)load
I, [2018-07-09T17:28:14.835254 #25076] INFO -- : PAGE: Browser: Safari 11.0 (iPhone)
I, [2018-07-09T17:28:14.835305 #25076] INFO -- : PAGE: UA: Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1
I, [2018-07-09T17:28:14.835360 #25076] INFO -- : PAGE: Resolution: 320x454
I, [2018-07-09T17:28:14.835408 #25076] INFO -- : PAGE: Resize, mw: 622px, md: false, fs: false
I, [2018-07-09T17:28:14.835457 #25076] INFO -- : PAGE: Using NChan
I, [2018-07-09T17:28:14.835505 #25076] INFO -- : PAGE: Mobile device
I, [2018-07-09T17:28:14.835556 #25076] INFO -- : AUTOPLAY: Not allowed
I, [2018-07-09T17:28:14.835608 #25076] INFO -- : STREAMS: Set method to JWplayer
I, [2018-07-09T17:28:14.835667 #25076] INFO -- : PUBSUB: Connected
I, [2018-07-09T17:28:14.835718 #25076] INFO -- : PUBSUB: Connected
PUBSUB: Connected
is emitted by pubsub.js
Pubsub = {
init: function () {
self = this;
self.online = false;
for (var i = 0; i < nchanUrls.length; i++ ) {
var nchanUrl = nchanUrls[i];
var sub = new NchanSubscriber(nchanUrl, { subscriber: ['websocket', 'longpoll'] });
sub.on('message', Pubsub.nchanMessage);
sub.on('connect', function(evt) {
self.online = true;
ajaxLog('PUBSUB: Connected');
});
sub.on('disconnect', function(code, text){
self.online = false;
if (!text) {
var evt = code;
code = evt.code;
text = evt.reason;
}
ajaxLog('PUBSUB: Disconnected: ' + code + ' desc: ' + text);
});
// sub.on('error', function(evt, desc){
// ajaxLog('PUBSUB: Error: ' + evt + ' desc: '+ desc);
// });
sub.start();
}
},
nchanMessage: function(message, message_metadata) {
// message is a string
// message_metadata is a hash that may contain 'id' and 'content-type'
message = JSON.parse(message);
eval(message.data.eval);
}
}
So connect
event was triggered, but NchanSubscriber
has received no events that were sent to /pub
endpoint
Looking at the nginx
access.log
I see a lot of lines with 499 response code:
212.0.0.226 - - [09/Jul/2018:17:29:35 +0000] "GET /sub/event/62728 HTTP/1.1" 499 11 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
212.0.0.226 - - [09/Jul/2018:17:29:35 +0000] "GET /sub/event/62728/private/682916 HTTP/1.1" 499 768 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
125.0.0.216 - - [09/Jul/2018:17:39:38 +0000] "GET /sub/event/62728 HTTP/1.1" 101 2 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
125.0.0.216 - - [09/Jul/2018:17:39:38 +0000] "GET /sub/event/62728/admin HTTP/1.1" 101 3720 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
194.0.0.145 - - [09/Jul/2018:17:46:44 +0000] "GET /sub/event/62728 HTTP/1.1" 499 12787 "-" "Mozilla/5.0 (Windows NT 10.0; rv:61.0) Gecko/20100101 Firefox/61.0"
212.0.0.226 - - [09/Jul/2018:17:49:59 +0000] "GET /sub/event/62728 HTTP/1.1" 101 3660 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
212.0.0.226 - - [09/Jul/2018:17:49:59 +0000] "GET /sub/event/62728/private/682916 HTTP/1.1" 101 2 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
184.0.0.122 - - [09/Jul/2018:17:52:32 +0000] "GET /sub/event/62728 HTTP/1.1" 499 12440 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15F79 [FBAN/FBIOS;FBAV/179.0.0.50.82;FBBV/116150041;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/11.4;FBSS/3;FBCR/KPNNL;FBID/phone;FBLC/nl_NL;FBOP/5;FBRV/0]"
184.0.0.122 - - [09/Jul/2018:17:52:32 +0000] "GET /sub/event/62728/private/684856 HTTP/1.1" 499 1546 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15F79 [FBAN/FBIOS;FBAV/179.0.0.50.82;FBBV/116150041;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iOS;FBSV/11.4;FBSS/3;FBCR/KPNNL;FBID/phone;FBLC/nl_NL;FBOP/5;FBRV/0]"
194.0.0.145 - - [09/Jul/2018:17:58:09 +0000] "GET /sub/event/62728/private/674743 HTTP/1.1" 499 1590 "-" "Mozilla/5.0 (Windows NT 10.0; rv:61.0) Gecko/20100101 Firefox/61.0"
212.0.0.226 - - [09/Jul/2018:18:14:51 +0000] "GET /sub/event/62728 HTTP/1.1" 499 17823 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
194.0.0.145 - - [09/Jul/2018:18:15:01 +0000] "GET /sub/event/62728 HTTP/1.1" 499 23055 "-" "Mozilla/5.0 (Windows NT 10.0; rv:61.0) Gecko/20100101 Firefox/61.0"
185.0.0.148 - - [09/Jul/2018:18:18:29 +0000] "GET /sub/event/62728 HTTP/1.1" 101 34975 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
185.0.0.148 - - [09/Jul/2018:18:18:29 +0000] "GET /sub/event/62728/admin HTTP/1.1" 101 1312607 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
185.0.0.148 - - [09/Jul/2018:18:18:29 +0000] "GET /sub/event/62728/private/684815 HTTP/1.1" 101 2 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
212.0.0.226 - - [09/Jul/2018:18:33:50 +0000] "GET /sub/event/62728/private/682916 HTTP/1.1" 499 738 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
212.0.0.226 - - [09/Jul/2018:18:33:54 +0000] "GET /sub/event/62728/private/682916 HTTP/1.1" 499 738 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
212.0.0.226 - - [09/Jul/2018:18:34:06 +0000] "GET /sub/event/62728 HTTP/1.1" 499 4351 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1"
194.0.0.145 - - [09/Jul/2018:18:34:16 +0000] "GET /sub/event/62728 HTTP/1.1" 499 4351 "-" "Mozilla/5.0 (Windows NT 10.0; rv:61.0) Gecko/20100101 Firefox/61.0"
So, long story short: NchanSubscriber
says we are connected, but won't receive anything from the server.
The questions I have:
pub
server is a separate server that listen local IP only? And there is a number of sub
locations in different serversNchanSubscriber
?NchanSubscriber
reconnect when connection is lost?Hi,
I'm getting this error when using the NPM package:
(node:12764) UnhandledPromiseRejectionWarning: TypeError: global.addEventListener is not a function
at new NchanSubscriber (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\nchan\NchanSubscriber.js:353:12)
at Client.bot.on (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\index.js:10:13)
at Client.emit (events.js:203:15)
at WebSocketConnection.triggerReady (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:125:17)
at WebSocketConnection.checkIfReady (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:141:61)
at GuildCreateHandler.handle (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\packets\handlers\GuildCreate.js:13:31)
at WebSocketPacketManager.handle (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:105:65)
at WebSocketConnection.onPacket (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
at WebSocketConnection.onMessage (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
at WebSocket.onMessage (C:\Users\afons\Documents\Projetos\Bots\bot_radioafonsosantos_status\node_modules\ws\lib\event-target.js:120:16)
(node:12764) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12764) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
May I get some support on this?
Thanks!
Greetings!
I initialise nChanSubscriber and listen for messages for a while and everything is OK. But after updating the page I receive all these messages again (no matter that in LocalStorage there is lastMessageId).
Here is my code:
const nchan = new NchanSubscriber(nChanUrl, {
subscriber: 'longpoll',
reconnect: 'persist',
shared: true
});
What should I change in order to get rid of this repetition?
Can an explicit license be added for the NchanSubscriber.js ?
Hi, thanks for the great module and the accompanying JS library.
Right now it is not possible to initiate an EventSource
connection with the withCredentials: true
parameter.
The line 673 looks like this
this.listener = new EventSource(url);
Since the CORS intent must be indicated in the constructor and not later, it must be solved on this line.
this.listener = new EventSource(url, { withCredentials: true });
Users would probably want to have a choice, so maybe pass it through the opt
array?
Thank you.
Some old browsers do not support web sockets. In that scenario will this client automatically use the secondary option like long polling?
Using this utility to subscribe to a pubsub route, how do we write a message to the publish end point?
Right now i'm trying to force it to use websockets and then i'm trying to get access to the websock so i can write a message but this seems like part of the nchan api that should be supported by the official client.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.