最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Unable to get session for socket in sailsjs after restart - Stack Overflow

programmeradmin4浏览0评论

I trying to build socket driven application on sailsjs, it is small and I need only memory session adapter, but when I restart application, I getting after socket.get('/'):

Could not parse: No session data returned, and an error was encountered saving session data for the first time: undefined SyntaxError {stack: (...), message: "Unexpected token N"} sails.io.js:142

Uncaught Error: Server response could not be parsed!
No session data returned, and an error was encountered saving session data for the first time: undefined 

I understand that my session is lost, but can't find any way to restore it, or even take care of this error.

Is there any way to request new session cookie for socket without reloading the page ?

I trying to build socket driven application on sailsjs, it is small and I need only memory session adapter, but when I restart application, I getting after socket.get('/'):

Could not parse: No session data returned, and an error was encountered saving session data for the first time: undefined SyntaxError {stack: (...), message: "Unexpected token N"} sails.io.js:142

Uncaught Error: Server response could not be parsed!
No session data returned, and an error was encountered saving session data for the first time: undefined 

I understand that my session is lost, but can't find any way to restore it, or even take care of this error.

Is there any way to request new session cookie for socket without reloading the page ?

Share Improve this question edited Aug 8, 2014 at 23:50 megawac 11.4k6 gold badges42 silver badges61 bronze badges asked Jan 14, 2014 at 5:59 zb'zb' 8,0593 gold badges43 silver badges68 bronze badges 2
  • Please post the code. – iConnor Commented Jan 14, 2014 at 20:31
  • @JustDon't I already did: socket.get('/');. On sailsjs just sails new testapp;cd testapp;sails lift; - open http://localhost:1337 in browser, kill app (^C) run sails lift and try to run socket.get('/') from browser console. – zb' Commented Jan 15, 2014 at 21:18
Add a ment  | 

2 Answers 2

Reset to default 13 +100

The problem here is that by default Sails uses MemoryStore to handle sessions, which means whenever you lower Sails (or whenever the application crashes, even if it is being restarted with forever, etc.) all the sessions will just be automatically gone.

The solution is as simple as changing the session handling to an external adapter. In config/session.js generated by default you already have two examples of setup for such an adapter, namely, for Redis and MongoDB, so all you have to do is to unment corresponding lines (and don't forget a ma after secret value). For example, if you go with mongo, it'll be something like

module.exports.session = {
  secret: 'c827f7e0dc520d83d63b5c9c055b1d00', // !!

  // Redis setup example is here...    

  // Unment the following lines to use your Mongo adapter as a session store
  adapter: 'mongo',
  host: 'localhost',
  port: 27017,
  db: 'sails',
  collection: 'sessions'

  // Optional Values:
  //
  // # Note: url will override other connection settings
  // url: 'mongodb://user:pass@host:port/database/collection',
  //
  // username: '',
  // password: '',
  // auto_reconnect: false,
  // ssl: false,
  // stringify: true    
};

Of course, in this case you should have mongod running on your machine.

UPDATE

Ok, if there is a MemoryStore limitation which can't be avoided (that was the original question), then reinitializing the socket session without reloading the page bees a bit tricky, but still possible. In order to do it one should:

  1. Make an AJAX (or JSONP in case of CORS) request to your server to get the new session ID. For example, it can be as simple as having a controller returning a JSON with the session ID, let's say api/controllers/TestController.js:

    module.exports = { index: function(req, res) { res.send(req.sessionID); } };

So, once you detected that the session is lost, use $.get('/test') to get the new session ID.

  1. Then pass the new session ID as a cookie parameter while reconnecting the socket:

    socket.socket.connect('/?cookie=<newSessionID>')

  2. socket.get("/", function (response) { console.log(response); }) will work after that.

It's kind of a quick hack, and there's probably a more elegant way to wrap it (e.g. send session ID in headers, not in the body, etc.), but the idea is simple: make an AJAX-request to get a new session and pass its ID as cookie parameter to reconnect the socket.

I had the same problem, and reading this issue i realised that a new session will be created just after an http request to sails. I have the front end served separately on static files, thus i use just socket.io towards sails, and this is the reason why the session is not renewed.

With either a persistent or volatile session adapter, when a session is expired it should be renewed.

So, without the need to switch to a persistent adapter, i just added an empty file under the sails assets folder, like in assets/js/renew-session.js (empty file), and included it as a script in the index of my app. This way, the initial HTTP request renews the cookies.

Maybe this can be useful to somebody else

发布评论

评论列表(0)

  1. 暂无评论