Open behrad opened 9 years ago
to fix socket.io when using in clustered mode, I don't know how to setup this store according to docs: http://docs.strongloop.com/display/SOPS/Socket+IO+store+for+clusters I have no access to the master process (no master.js) in loopback app when running by slc run ... my server.js code is put into strongloops cluster workers.
In your app script, you need to configure socket.io to use a custom session store:
var socketIO = require('socket.io');
var ClusterStore = require('strong-cluster-socket.io-store')(socketIO);
app.io = socketIO( app.start(), { store: new ClusterStore() });
As for configuring the master process, I am not sure if slc run
has any support for that. Perhaps @sam-github will know more?
Regardless of the solution, I don't know if this module works with socket.io 1.0. The new version of socket.io uses a new concept of adapters for passing events between nodes, and it relies on sticky sessions to prevent the problem that strong-cluster-socket.io-store was attempting to fix. See http://socket.io/docs/using-multiple-nodes/ for more details.
Doesn't work with slc run
, sorry.
So if it is a strong-cluster-socket.io-store, how couldn't it support strongloop runtime?
With which loopback/strong-pm config we can use this module? Or is this targeting plain node.js cluster module?
It is targeting plain node cluster module, never saw significant uptake or ue, predates the beginning of work on strong-supervisor by half a year (and of strong-pm by much more), and socket.io 1.x has other mechanisms to deal with this.
I'm sorry you were hoping to use this, perhaps if you decribe the problem you are trying to solve we can provide better suggestions.
I have a loopback 2 app with socket.io with the builtin strongloop cluster support. I was unable to use sticky session (OR socket.io-redis) to fix my websocket issues in clustered mode.
What version of socket.io, what version of socket.io-redis, and what was the issue?
Using socket.io with external redis is typical use-case, I'm surprised it didn't work.
"socket.io": "^1.3.5",
"socket.io-redis": "^0.1.4"
bootstrapped as below:
app.io = socketIO( app.start() );
var redis = require('socket.io-redis');
app.io.adapter(redis({
host: config.broker.backend.host,
port: config.broker.backend.port
}));
but in default non-websocket client connection mode, with polling handshake client complains about the famous websocket error.
yes because the client is trying to make the handshake with different workers, I was looking if the slc run in production mode was compatible with sticky sessions, so for what Im seeing here is that I need to setup the workers by my own instead of using NODE_ENV="production" slc run, right?
any updates on this issue?. I am having the same problem now
Anybody use socket.io under strong-pm and nginx???. I Have problems to run my socket.io app under strong-pm using the nginx to proxy ...
Anybody use socket.io under strong-pm?? Please share how to setup socket.io using strong-pm
Yes I use it What is your problem??
how can i configure server.js to make socket.io work using strong-pm. When i use slc run it works fine for me but when i deploy in prod using strong-pm it not work. I have this error.
HTTP Response {"code":1,"message":"Session ID unknown"}
I know is the cluster so if you have any example of server.js please share.
If you use strong-pm, I supouse you are using more than one node, so in this situation you could you the the redis adapter for socket.io.
1) Install redis (sudo apt get install redis-server) in Linux 2) Install redis adapter
npm install socket.io-redis --save
2) In the server.js inject the adapter inside socket.io.
/* inject socket.io server inside app */
app.io = require('socket.io')(app.start());
// configure the socket.io adapter using redis like pubsub messages manager
// to replicate the events and handshake between all cluster worker process
var redis = require('socket.io-redis');
try {
app.io.adapter(redis({host: 'localhost', port: 6379}));
}
catch(err) {
logger.error('Error connecting to redis' , {fileName: 'server.js', method: 'boot', stack: err.stack});
}
4) If you are using nginx:
The socket balancesd is made by the master process inside strong-pm so you don't need nginx balancer if you use only one instance, if you use more than one instance you'll need a balancer like nginx capacity.
...
location /socket.io{
proxy_pass http://app.tachoexplorer.com/socket.io;
# enables WS support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
...
This is my server.js and still get the same problem (redis is installed and nothing in logs)
var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
console.log('Web server listening at: %s', app.get('url'));
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module) {
//Comment this app.start line and add following lines
//app.start();
app.io = require('socket.io')( app.start() );
// configure the socket.io adapter using redis like pubsub messages manager
// to replicate the events and handshake between all cluster worker process
var redis = require('socket.io-redis');
try {
app.io.adapter(redis({host: 'localhost', port: 6379}));
}
catch(err) {
logger.error('Error connecting to redis' , {fileName: 'server.js', method: 'boot', stack: err.stack});
}
}
});
The error that you show is from server side or client side??. When you obtain this error??
The problems that I had was from client-side because I lost some messages, then I used the redis adapter and resolve the problem in the cluster (strong-pm)
from client side http://xxxx:3000/socket.io/?EIO=3&transport=polling&t=LJY-vzd&sid=MXU5rgpu03dtvJ6LAAAH I get this : {code: 1, message: "Session ID unknown"}
It works the first time but if i refresh the page i get this error
Ok try this when you create the socket manager in the client side:
var socket = io({transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling', 'polling']});
With this you force to use websocket.
I use angular.js in the client side so I use angular-socket.io to manage socket like a service. Do you use angular in the client side?
Yes i use angular in client side
where do you use this var socket = io({transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling', 'polling']});
Ok perfect, I use the socket io client side and the angular wrapper over the socket.io client:
"socket.io-client": "~1.4.4",
"angular-socket-io": "~0.7.0"
So in the in the app.js (init file) you define the socket factory like this:
app.config(function ($provide) {
// inject the Push socket in the app angular module
$provide.factory('Socket', function (socketFactory, Context) {
var socket = io({transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling', 'polling']});
return socketFactory({ioSocket: socket});
});
Then you could use this factory like other ...
This is all the configuration in the server side and in the client side than I use under the strong-pm cluster.
I had the same issue as you are describing, and for me it was like this: It is hard to control to which node your connection is being redirected by using strong-pm, and mostly the session Id is not shared among all instances, so sending authentication right after connection would always fail for me. I have not trying to control the inbound connections using ngix but I guess that the strong-pm is the one that does the balancing inside the same host. What I did: Created a new project just and I control the connections redirecting to the same worker process, an external load balancer with session control as well to redirect to the same host. In this approach you have to use redis to send messages across nodes. I tried to use socket-io.emitter but it didn't work for me, around 6 months ago. Another approach you can use is to use a MQ and check node by node to find your desired client, etc
Thanks for your help
I'm still having trouble implementing socket.io while running "slc run --cluster 4". I'm using the redis adapter, and i tried @masalinas solution with no luck. Any suggestions?
Having the same issue as talpasco. When I tried masalinas suggestion, I was able to get socket connection but no messages where emitted (or received) Any ideas why?
I have a loopback v2 app using socket.io:
to fix
socket.io
when using in clustered mode, I don't know how to setup this store according to docs: http://docs.strongloop.com/display/SOPS/Socket+IO+store+for+clusters I have no access to the master process (no master.js) in loopback app when running byslc run ...
my server.js code is put into strongloops cluster workers.I am attaching socket.io this way in my server.js