express-socket.io-session icon indicating copy to clipboard operation
express-socket.io-session copied to clipboard

Bug when socket.io connects before first HTTP connection

Open FlorianWendelborn opened this issue 10 years ago • 20 comments

Hi, I discovered a bug (or maybe just a weird unexpected behavior) with this module.

Description:

When socket.io connects before express.js gets one HTTP request, socket.io gets a new session ID every time it reconnects. As soon as one HTTP request reaches the server, the session ID is static. This leads to unexpected behavior when a socket reconnects after a server restart or network problem.

Code to reproduce:

// bug.js
var app = require('express')(),
    server  = require("http").createServer(app),
    io = require("socket.io")(server),
    session = require("express-session")({
        secret: "my-secret",
        resave: true,
        saveUninitialized: true
    }),
    sharedsession = require("express-socket.io-session");

// Attach session
app.use(session);

app.get('/', function (req, res) {
    console.log('express id: ' + req.session.id);
    res.sendFile(__dirname + '/bug.html');
});

// Share session with io sockets
io.use(sharedsession(session));

io.on("connection", function(socket) {
    console.log('socket.io id: ' + socket.handshake.session.id);        
});

server.listen(3000);

<!--bug.html-->
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io('http://localhost:3000', {
            reconnection: false
        });
        function httpGet() {
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.open( "GET", 'http://localhost:3000', false );
            xmlHttp.send( null );
            return xmlHttp.responseText;
        }
    </script>
</head>
<body>
    <button onclick="socket.disconnect();">disconnect</button>
    <button onclick="socket.connect();">connect</button>
    <button onclick="httpGet();">http</button>
</body>
</html>

Steps to reproduce:

  1. node bug
  2. Load http://localhost:3000 in browser
  3. ^C (close node)
  4. node bug
  5. Click on connect
  6. Click on HTTP
  7. Click on disconnect
  8. Click on connect

Example Log Output using the above steps:

>node bug
express id: eesau4KnEaNBu9dxc-sd-AsWxOC2pkmx
socket.io id: eesau4KnEaNBu9dxc-sd-AsWxOC2pkmx
^C
>node bug
socket.io id: unGp5Xct-q0sYJQanm5G4R40kBOad6do
express id: N8eXurfyMeqMsIJDf5azw7ZYCwnJkzuy
socket.io id: N8eXurfyMeqMsIJDf5azw7ZYCwnJkzuy

FlorianWendelborn avatar Jun 11 '15 12:06 FlorianWendelborn

Thanks! I've noticed that when unit testing using socket.io-client. Somehow I managed to ignore that issue. Do you have an approximate idea of what would be the expected behaviour? Or, I mean, the solution?

oskosk avatar Jun 11 '15 12:06 oskosk

Sorry, I closed the issue by error. I reopened it

oskosk avatar Jun 11 '15 12:06 oskosk

No, I have no idea how to fix this, but I'd expect socket.io to initialize the session if express didn't already do it.

FlorianWendelborn avatar Jun 11 '15 12:06 FlorianWendelborn

OK, I'll fix the code to behave as expected. Thanks!

oskosk avatar Jun 11 '15 13:06 oskosk

Any news on this?

FlorianWendelborn avatar Jun 27 '15 23:06 FlorianWendelborn

+1

jlbribeiro avatar Nov 07 '15 19:11 jlbribeiro

Sorry. I'll get back to this

On Sat, Nov 7, 2015, 4:25 PM José Ribeiro [email protected] wrote:

+1

— Reply to this email directly or view it on GitHub https://github.com/oskosk/express-socket.io-session/issues/6#issuecomment-154741264 .

oskosk avatar Nov 07 '15 21:11 oskosk

Weird things happened. when using var socket = io('http://localhost:3000') or var socket =io('/') in the client html ,sock.io session id is differing from express and will change after refresh. however when using var socket=io() suddenly everything is right in place

wywzxxz avatar Sep 11 '16 13:09 wywzxxz

@wywzxxz You seem to be right, when providing a connection URL (client-side) the session ID this module gives is different from the actual session ID. Without a connection string passed it does seem to work as expected however.

Could we get an explanation as to why this is and possibly a fix?

starwolfy avatar Nov 02 '16 15:11 starwolfy

Any news about the original bug? Any work-around?

idoadiv avatar Mar 21 '17 13:03 idoadiv

Hi Guys , same issue every time i refresh the page session Id will change and while accessing the session variable it shows "undefined" please help

thetechguy2016 avatar Jun 28 '17 07:06 thetechguy2016

It is because socket.io doesn't make a new http request therefore the session data isn't available as express doesn't send the session forward. If you don't refresh the http connection socket.io will still connect behind the scene skipping express.

Perhaps if session id doesn't match in the above example, do http() then connect() to refresh the session through express?

adam4813 avatar Nov 22 '17 13:11 adam4813

I'm having the same problem with the Socket.io sessionID being different from the Express sessionID. @adam4813 would you be so kind to provide a snippet of your suggestion?

n-david avatar Nov 28 '17 10:11 n-david

When socket.io connects before express.js gets one HTTP request, socket.io gets a new session ID every time it reconnects.

Does this also happen if saveUninitialized: false? I mean, can I eliminate the possibility of this bug by setting that, if my application permits?

ha7ilm avatar Mar 05 '18 08:03 ha7ilm

I was having the same issue. I had to send a dummy ajax request to the express server to trigger the session creation in the browser. Then I run the socket = io(server_endpoint); in the ajax callback . It seems to be all working fine.

islei avatar Aug 07 '18 06:08 islei

Still an issue especially If you are trying to handle the session exceptionally over socket connections.

Fabiansson avatar Mar 07 '20 18:03 Fabiansson

still an issue

siluri avatar Mar 27 '20 10:03 siluri

But workaround from @islei works!

Fabiansson avatar Mar 27 '20 11:03 Fabiansson

doesnt work for me sorry.

siluri avatar Mar 27 '20 12:03 siluri

Hi everybody.

When I use the path

var socketApp = io.of('/socket/app').on('connection', (socket) => { //Not working

But

var socketApp = io.of('').on('connection', (socket) => { // Working

I don't know the reason,

danieden avatar Apr 19 '21 09:04 danieden