slact / nchan.js

NPM package for the Javasript client for Nchan
Other
91 stars 25 forks source link

Shared connection causes delay and breaks in IE #3

Closed gazugafan closed 7 years ago

gazugafan commented 7 years ago

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?

slact commented 7 years ago

So, to be clear, you're seeing a 20-second delay on all browsers, and not working at all on IE11, right?

gazugafan commented 7 years ago

Yes, with shared=true I'm seeing a connection delay (10-20 seconds) in Firefox, Chrome, and IE11. In Firefox and Chrome, after the connection delay I get a connect event and everything works like normal after that. In IE11, after the 10-20 second delay I get a disconnect event (but not a connect event). Haven't tested Edge or Safari. Thanks for you help!

slact commented 7 years ago

Last thing, can you show me the Nginx config for the "/sub/test" location that NchanSubscriber connects to?

It sounds like there's a bug in the master-promotion lottery algorithm for the connection sharing option. I'll investigate it over the next few days.

gazugafan commented 7 years ago

Sure thing! Thanks so much for looking into it.

http {
    #Global NCHAN preferences...
    nchan_max_reserved_memory 1G;
    nchan_message_buffer_length 500;

    server {
        #publishing is available only on localhost
        listen 127.0.0.1:80;
        location ~ /pub/(.*)$ {
            nchan_publisher;
            nchan_channel_id "$1";
            nchan_channel_id_split_delimiter ",";
        }
    }

    server {
        listen 80;
        #listen 443 ssl;
        #SSL config goes here in production
        location ~ /sub/(.*)$ {
            nchan_subscriber;
            nchan_channel_id "$1";
            nchan_channel_id_split_delimiter ",";
            nchan_subscriber_first_message oldest;
        }
    }
}
slact commented 7 years ago

Ok, looks like I left some variables un-renamed after a refactor which caused the problem. Fixed in 57f1e96514d24bb7f , and released to NPM as version 1.0.3 . Please give it another try and let me know if the issue is fixed for you as well.

gazugafan commented 7 years ago

The issue seems to have improved some, but maybe not entirely fixed? Also noticing some fun new console logs about bananas and dice rolls! Some observations I've made so far:

Here are some of the relevant logs from different browsers when trying to establish a single connection, in case that helps. The "connect" and "disconnect" logs followed by an object are the connect and disconnect events. Thanks again for your looking into it!

Firefox (shared off)

17:57:46.108 not a banana probably  app.js:45554:3
17:57:46.889 GET 
http://localhost/sub/common [HTTP/1.1 101 Switching Protocols 2ms]
17:57:47.520 connect  app.js:33318:17
17:57:47.521 open { target: WebSocket, isTrusted: true, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, composed: false, timeStamp: 1492297067520000, cancelBubble: false, originalTarget: WebSocket }  app.js:33319:17

Firefox (shared on)

17:55:53.017 not a banana probably  app.js:45555:3
17:55:53.019 status == disconnected, maybepromotetomaster  app.js:45938:9
17:55:55.092 roll, bestroll 0.28549363653504367 0.28549363653504367  app.js:45864:5
17:55:55.093 1492296953.019 1492296953.093  app.js:45873:7
17:55:55.094 winner, no more contenders!  app.js:45875:9
17:55:55.095 finish  app.js:45839:5
17:55:55.095 master  app.js:45841:5
http://localhost/sub/common [HTTP/1.1 101 Switching Protocols 1ms]
17:55:55.779 connect  app.js:33319:17
17:55:55.780 open { target: WebSocket, isTrusted: true, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, composed: false, timeStamp: 1492296955777000, cancelBubble: false, originalTarget: WebSocket }

Chrome (shared off)

2017-04-15 17:54:30.768 NchanSubscriber.js:81 not a banana probably
2017-04-15 17:54:30.810 event-buffer.ts:33 connect
2017-04-15 17:54:30.810 event-buffer.ts:34 Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2…}

Chrome (shared on)

2017-04-15 17:53:01.096 NchanSubscriber.js:81 not a banana probably
2017-04-15 17:53:13.115 NchanSubscriber.js:390 roll, bestroll 0.584756910929964 0.584756910929964
2017-04-15 17:53:13.115 NchanSubscriber.js:399 1492296791.114 1492296791.115
2017-04-15 17:53:13.115 NchanSubscriber.js:401 winner, no more contenders!
2017-04-15 17:53:13.116 NchanSubscriber.js:365 finish
2017-04-15 17:53:13.116 NchanSubscriber.js:367 master
2017-04-15 17:53:13.119 event-buffer.ts:34 connect
2017-04-15 17:53:13.119 event-buffer.ts:35 Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2…}

IE11 (shared off)

not a banana probably
connect
[object Event]

IE11 (shared on)

not a banana probably
status == disconnected, maybepromotetomaster
new bestRoll 0.011614050178315071
roll, bestroll 0.011614050178315071 0.011614050178315071
1492297327.596 1492297327.6
winning, but have contenders 1
roll, bestroll 0.011614050178315071 0.011614050178315071
1492297327.596 1492297329.602
winner, no more contenders!
finish
master
demote to slave
disconnect
[object CloseEvent]
***Delay of about 10 seconds here
new bestRoll 0.9563517320936706
roll, bestroll 0.9563517320936706 0.9563517320936706
1492297341.607 1492297341.608
winning, but have contenders 1
roll, bestroll 0.9563517320936706 0.9563517320936706
1492297341.607 1492297343.61
winner, no more contenders!
finish
master
connect
[object Event]
slact commented 7 years ago

Ah, ok. Looks like npm publish published the working copy, whereas I expected it to publish the last git commit. So some un-checked-in debug statements made it in.

I'll look into the connection issue to multiple urls, and do some more IE11 testing, and will update this by tomorrow.

slact commented 7 years ago

Alright then, there were 2 separate issues that needed fixing:

First, there was a shared variable that prevented shared subscribers to different urls from starting. That was fixed as part of the shared-subscriber refactoring in 96a0a3168d81b8.

Second, the IE issue was because IE still likes to do things its own stupid way. The fix is in 40a45d022dd75. (It had to do with localStorage update events being sent to the originating window, which normal browsers don't do). To see this work correctly in IE, you may need to clear your localStorage, or let it throw an error once or twice, it should not happen again after that.

I've also added a limitation to the shared mode: only 1 running subscriber is allowed per url per window/tab. Well, this limitation was there from the start, I'm just throwing an error about it rather than letting it fail silently.

Anyway, I've updated the npm package to 1.0.4.. Hopefully this fixes everything. Please double-check that it works for you too.

gazugafan commented 7 years ago

Seems to be working great now! Thanks so much for digging into it, and thanks a million for NCHAN. It's infinitely useful in a fundamental way--like NGINX itself.

slact commented 7 years ago

Excellent. And I'm quite glad you're finding Nchan useful. If you really want to, you can drop a few satoshis in the tip jar. (Dollars and cents are ok too I guess.)