primus: Middleware example is outdated, can't get it working anymore

Version: 6.0.8

Environment:

  • Operating system: Windows 10
  • Browser: Google Chrome
  • Node.js: 7.3.0
  • Transformer: uws

Expected result: Establish a connection between server and client Able to set and read session object shared between Express and Primus

Actual result: If I set

primusSession.upgrade = true // or not set it at all

I can read and set the session object at spark.request.session as expected. However, I get the following error in my browser when trying to connect

WebSocket connection to 'ws://localhost:3000/gameserver?_primuscb=LcrjIwC' failed: Connection closed before receiving a handshake response
opening @ primus.js:3212
emit @ primus.js:300
reconnect @ primus.js:3246
emit @ primus.js:279
reconnect @ primus.js:2341
emitter @ primus.js:146
emit @ primus.js:1007
delay @ primus.js:849
tickedtock @ primus.js:1316

If I set

primusSession.upgrade = false

The browser connects to the client successfullly however the middleware doesn’t get called at all, and I can’t set or read sessions in Primus.

Steps to reproduce:

I’ll try to set up a clean project to reproduce the issue, but here are code snippets for now.

primus-session.js

/**
 * Slightly modified version of this middleware example
 * Notably, all references to cookie-parser have been rewritten since the latest express-session module doesn't use it anymore
 * https://github.com/primus/primus/blob/master/examples/middleware/session.js
 */

'use strict'

//
// Expose the configuration function.
//
module.exports = function configure(options) {
    const store = options.store
    const primus = this

    if (!store) {
        //
        // Throw an error when the session store is not passed.
        //
        const message = 'Session middleware configuration failed due to missing '
            + '`store` option'
        throw new Error(message)
    }

    //
    // The actual session middleware. This middleware is async so we need 3
    // arguments.
    //
    function session(req, res, next) {
        //
        // The session id is stored in the cookie
        //
        const sid = req.headers.cookie
        console.log('sid:', sid)

        //
        // Default to an empty session.
        //
        req.session = {}

        //
        // If we don't have a session id we are done.
        //
        if (!sid) return next()

        //
        // Grab the session from the store.
        //
        store.get(sid, function (err, session) {
            //
            // We don't want to kill the connection when we get an error from the
            // session store so we just log the error.
            //
            if (err) {
                primus.emit('log', 'error', err)
                return next()
            }

            if (session) req.session = session

            next()
        })
    }

    // Don't call this middleware in an Upgrade request
    session.upgrade = false
    session.http = true

    return session
}

Express configuration

// Sessions are shared between Express and Primus
const store = new expressSession.MemoryStore()
const session = expressSession({
    secret: 'change in production',
    resave: true,
    saveUninitialized: true,
    store,
})

// Express settings and middleware
app.set('port', process.env.PORT || 3000)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')
app.use(logger('dev'))
app.use(express.static(path.join(__dirname, 'public')))
app.use(session)

Primus configuration

const primus = new Primus(server, {
    pathname: '/gameserver',
    transformer: 'uws',
})

// Primus middleware
primus.use('session', primusSession, { store })
primus.use((req, res) => {
    console.log(req.session)
})

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (11 by maintainers)

Most upvoted comments

My bad, I forgot to run npm install in the top level directory while trying to run the example. I can confirm that the example works.

So the Primus example works for you on Windows when using uws?

I meant that the middleware example in /examples runs without any modification (using websockets as default transformer).


Hmm, that’s surprising. Feel free to close the issue, I’ll create another one at uws. Thanks for all the help!

@prashcr sockjs is “special” as it overrides the session property. If you change the Primus example like this:

diff --git a/examples/middleware/index.js b/examples/middleware/index.js
index 5037429..45a1ada 100644
--- a/examples/middleware/index.js
+++ b/examples/middleware/index.js
@@ -52,7 +52,7 @@ app.get('/', function index(req, res) {
 // Create an HTTP server and our Primus server.
 //
 var server = http.createServer(app)
-  , primus = new Primus(server);
+  , primus = new Primus(server, { transformer: 'sockjs' });
 
 //
 // Here we add the `cookie-parser` middleware and our session middleware. The
@@ -66,7 +66,7 @@ primus.on('connection', function connection(spark) {
   //
   // Our session data can now be read from `spark.request.session`.
   //
-  spark.write(JSON.stringify(spark.request.session, null, '  '));
+  spark.write(JSON.stringify(spark.request.banana, null, '  '));
 });
 
 //
diff --git a/examples/middleware/session.js b/examples/middleware/session.js
index e12b46e..47bb6ae 100644
--- a/examples/middleware/session.js
+++ b/examples/middleware/session.js
@@ -33,7 +33,7 @@ module.exports = function configure(options) {
     //
     // Default to an empty session.
     //
-    req.session = {};
+    req.banana = {};
 
     //
     // If we don't have a session id we are done.
@@ -53,7 +53,7 @@ module.exports = function configure(options) {
         return next();
       }
 
-      if (session) req.session = session;
+      if (session) req.banana = session;
 
       next();
     });

it works and that’s another reason why expression-session shouldn’t be used directly.


My bad, I forgot to run npm install in the top level directory while trying to run the example. I can confirm that the example works.

So the Primus example works for you on Windows when using uws?