yehya / express-longpoll

Lightweight long polling for express.js
ISC License
33 stars 13 forks source link

Publish seems to round robin instead of actually publishing #7

Closed JamesRBrown closed 4 years ago

JamesRBrown commented 6 years ago

I set up test code according to the read me. Basically copied and pasted the server side code into a testServer.js file. Then ran it.

Also created a simple client html file to do the client long poll example.

With one client, things worked exactly as expected. Every 5 seconds I saw "Some data" logged to the browser's console.

So I opened another browser window, and hit the same /poll URL. Now I was seeing "Some data" logged to one browser console, and then to the other browser console, every 5 seconds. So each browser would see "Some data" every 10 seconds, because each interval was only sending data to one client.

I then opened a third browser. The amount of time for a give client to see "Some data" increased to 15 seconds, and with all three windows where I could see the console, I could see one client get a response, then in five seconds the next, and then in five more second the next, and it just round robined between each client.

The expected behavior is for longpoll.publish to send out to all clients all at once, this is not what is happening. It's like there is a stack, and each time publish it called, it's popping a subscriber off the stack. So the next time publish is called the next subscriber is serviced, and so on.

JamesRBrown commented 6 years ago

If you use the following code, you can watch the "sentCount" alternate between clients:

` (function(){

var express = require('express');
var app = express();
//var longpoll = require("express-longpoll")(app);
var longpoll = require("express-longpoll")(app, { DEBUG: true });

app.use('/static', express.static('static'));

// Creates app.get("/poll") for the long poll
longpoll.create("/poll");

app.listen(3000, function() {
    console.log("Listening on port 3000");
});

var data = { text: "Some data",
sentCount: 0};

// Publishes data to all clients long polling /poll endpoint
// You need to call this AFTER you make a GET request to /poll
data.sentCount++;
longpoll.publish("/poll", data);

// Publish every 5 seconds
setInterval(function () { 
    data.sentCount++;
    longpoll.publish("/poll", data);
}, 5000);

})();
`

On client one's console you see:

{text: "Some data", sentCount: 1} {text: "Some data", sentCount: 3} {text: "Some data", sentCount: 5} {text: "Some data", sentCount: 7}

On client two's console you see:

{text: "Some data", sentCount: 2} {text: "Some data", sentCount: 4} {text: "Some data", sentCount: 6} {text: "Some data", sentCount: 8}

yehya commented 4 years ago

Holy shit this one was a tough one to figure out. Thanks for submitting this.

I wrote a test to specifically test this and it passed with no issues, however I was able to reproduce what you are talking about. The issue here is Google Chrome.

https://github.com/expressjs/express/issues/3863

If you use firefox with several tabs this issue does not happen. Not sure what Chrome is doing to cause this. Anyway, shouldn't happen with multiple devices.

Basically this has never been an issue, Chrome just makes it seem like there's something wrong in the code.