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 justsails new testapp;cd testapp;sails lift;
- openhttp://localhost:1337
in browser, kill app (^C
) runsails lift
and try to runsocket.get('/')
from browser console. – zb' Commented Jan 15, 2014 at 21:18
2 Answers
Reset to default 13 +100The 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:
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.
Then pass the new session ID as a
cookie
parameter while reconnecting the socket:socket.socket.connect('/?cookie=<newSessionID>')
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