socket.io javascript client fails to reconnect after restarting server - node.js

I'm using "socket.io": "1.4.5","socket.io-redis": "1.0.0". The javascript client using socket-io-client seems to be happily connecting to the server except for when the server is restarted. The connection attempt fails triggering 'connect_error' event with message '{"message":"xhr poll error", "type":"TransportError","description":0"}'. If I restart by browser the connection works just fine. I also noticed that if I set a breakpoint in event handler for 'connect_error' and wait for a few seconds it the connection attempt succeeds eventually. I'm missing something a config setting in client code? here is the client code I have
var socketConnectParams = {'max reconnection attempts': 150};
socketConnectParams['reconnection'] = true;
socketConnectParams['reconnectionDelay'] = 5000;
socketConnectParams['reconnectionDelayMax'] = 15000;
var socket = io('http://localhost:8888', socketConnectParams);
socket.on('connect', function () { });
socket.on('connect_error', function(error) {
dLog("connection error event received." + JSON.stringify(error));
});

I listen to a "disconnect" event to rebind a new 'connect' event. This way, if you server is restarted, the local client will detect this and create a new listener for then the server comes up again. Maybe you could try that.
socket.on('disconnect', function(){
socketCleanup(); // this is a function to cleanup all listeners, just in case, so you can restart fresh
socket.on('connect', function(){
socketConnect();
});
});

Related

Nodejs request proxy stream(mjpeg) connection never ends

(unnecessary backstory)
I have a nodejs server with expressjs framework that's proxy streaming a webcam feed. The reason I need this is because the mjpg stream must come from this server due to complex CORS issues.
//proxy from webcam server to avoid CORS complaining
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
request(url).pipe(res);
});
question :
The issue is simple. request(url).pipe(res) never closes, because the source is mjpeg which literally never ends. I need to find a way to force close this pipe when the client(browser; the destination) is no longer available - as in, closes the window.
The other answers did not work for me.
This line var pipe=request(url).pipe(res);
returns the pipe instead of the request object. So I needed to break the line up.
The request object is needed to abort. Calling the .end() didn't work either, but the .abort() did the trick. It took me hours to find the answer that worked for me, so I thought I would share.
app.get('/cam/frontdoor',function(req,res){
var request_options = {
auth: {
user: '',
pass: ''},
url: 'http:/xx.xx.xx.xx/mjpg/video.mjpg',
};
var req_pipe = request(request_options);
req_pipe.pipe(res);
req_pipe.on('error', function(e){
console.log(e)
});
//client quit normally
req.on('end', function(){
console.log('end');
req_pipe.abort();
});
//client quit unexpectedly
req.on('close', function(){
console.log('close');
req_pipe.abort()
})
})
Use socket.io to monitor the remote connection
// install it on your project
npm install socket.io
// require it on server side
var socket = require('socket.io');
// listen for sockets from your server
var mysocks = socket.listen(myexpressappvar);
// keep collection of sockets for use if needed
// its good practice
var connectedSockets = [];
// add event handelers on server side
mysocks.sockets.on("connection", function(socket){
// add socket to our collection
connectedSockets.push(socket);
// you will need to bind their stream id here.
exe.....
// listen for disconnected
socket.on("disconnect", function(){
// remove socket from collection
connections.splice(connections.indexOf(socket), 1);
// destory stream here
exe...
});
});
// last thing, is add socket.io to the client side.
<script src="/socket.io/socket.io.js"></script>
// then call connect from client side js file
var socket = io.connect();
I have found out a simpler way. Add a event listener for client connection closing, and force close the pipe when it happens.
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
var pipe=request(url).pipe(res);
pipe.on('error', function(){
console.log('error handling is needed because pipe will break once pipe.end() is called')
}
//client quit normally
req.on('end', function(){
pipe.end();
}
//client quit unexpectedly
req.on('close', function(){
pipe.end();
}
});

how to capture connection error in client side socket.io?

i am new to socket.io. i want to notify user when the internet connection drops
or failed to connect to the server in socket.io. in client pc if we drop the internet connection, socket.io makes xhr pooling to connect to the server. My intention is to notify the user when ever the connection drops or server is down and client failed to connect it.
The following code is of client side socket.io app, but following events never fires when ever internet connection failed or server is down.
var socket = io('http://192.168.1.109:3000');
socket.on("private msg", function (data) {
console.log(data.msg);
});
socket.on("conect_error", function (data) {
console.log("connect)error");
// this event never fires
});
socket.on("connect_timeout",function(){
console.log("connection timeout");
//this event never fires
});
socket.on("reconnect", function () {
console.log("reconnected");
// this works fine
});
socket.on("disconnect",function(){
console.log("disconnected");
// this works fine
});

when is the 'connect' event in nodejs net module emitted?

I have this simple TCP server:
var net = require('net');
var server = net.createServer(function (socket) {
socket.on('connect', function() {
console.log("New client!");
});
});
server.listen(8000, function(){
console.log("server running...")
});
and then I have another file as client.js:
var net = require('net');
var client = net.connect({port: 8000},
function() {
console.log('client connected');
});
client.on('error', console.error);
I run server in one terminal window and then I run client in other window and expect to see server log "New Client". Although, that doesn't happen. So, when is the 'connect' event exactly emitted?
net.createServer sets the given function as a listener to the connection event.
In other words, on the server side, the socket is already connected when you get the callback, and the event you're trying to listen to isn't emitted on an already connected socket.
I made a different test. The server object has "timeout" property. When you call the follow code:
server.setTimeout(500); //Now after 0,5 second you can call "connection" event.
The default value is 120000.
But, I still have no idea what this change will cause.

Socket.io - Close Server

I have a socket.io server in my app, listening on port 5759.
At some point in my code I need to shutdown the server SO IT IS NOT LISTENING ANYMORE.
How Can I accomplish this?
Socket.io is not listening on an http server.
You have a server :
var io = require('socket.io').listen(8000);
io.sockets.on('connection', function(socket) {
socket.emit('socket_is_connected','You are connected!');
});
To stop recieving incoming connections
io.server.close();
NOTE: This will not close existing connections, which will wait for timeout before they are closed. To close them immediately , first make a list of connected sockets
var socketlist = [];
io.sockets.on('connection', function(socket) {
socketlist.push(socket);
socket.emit('socket_is_connected','You are connected!');
socket.on('close', function () {
console.log('socket closed');
socketlist.splice(socketlist.indexOf(socket), 1);
});
});
Then close all existing connections
socketlist.forEach(function(socket) {
socket.destroy();
});
Logic picked up from here : How do I shutdown a Node.js http(s) server immediately?
This api has changed again in socket.io v1.1.x
it is now:
io.close()
The API has changed. To stop receiving incoming connections you should run:
io.httpServer.close();

How does one properly shutdown socket.io / websocket-client?

I'm trying to create a test using LearnBoost's socket.io and the node-websocket-client. Communication between the client and server work great. After all communication is done, I close both the client and the server. Yet the program hangs, waiting on some unknown callback. Two questions:
What is the following program waiting for?
Is there a tool for diagnosing outstanding callbacks in node programs?
var connect = require('connect'),
io = require('socket.io'),
WebSocket = require('websocket-client').WebSocket;
var port = 7111;
var server = connect.createServer();
var socket = io.listen(server);
socket.on('connection', function(client) {
client.send('Welcome!');
client.on('message', function(message) {
console.log(message);
});
client.on('disconnect', function() {
console.log('closing');
server.close();
});
});
server.listen(port, function() {
var ws = new WebSocket('ws://localhost:' + port + '/socket.io/websocket');
ws.onmessage = function(message) {
console.log(message.data);
};
setTimeout(function() {
ws.send('~m~3~m~Yo!');
ws.close();
}, 10);
});
EDIT: changed the variable name of the WebSocket to ws to avoid confusion
var socket = io.listen(server);
You've created a socket on a port. You've never closed it.
socket.server.close() closes your (socket.io) socket.
When in doubt read the socket.io github examples
socket.server === server It's the server you pass in, in the liste statement so it's closed. I'm not sure what it's waiting for.
Below a way to shutdown all the connections and be able to run multiple expresso tests (using socket.io and socket.io-client).
The solution is tricky and buggy but works on 0.8.5. The main problem is regarding the library to use websockets (node-websocket-client).
Currently, on socket.io, the OS contributors have patched the websocket client. So, we must do the same on our socket.io-client npm package to be able to use finishClose method on the socket client side. Socket.io-client uses the websocket library as npm package, so you must find the file (websocket.js) and substitute it with the same on socket.io.
Afterwards, you could use finishClose method to ensure the connections are closed and with some custom server/client socket settings, the tests will run correctly.
var io = require("socket.io").listen(port);
io.set('close timeout', .2);
io.set('client store expiration', .2);
var client = require("socket.io-client").connect( "http://localhost", { port: port , 'reconnect': false, 'force new connection': true});
client.on('connect', function() {
client.disconnect();
});
client.on('disconnect', function() {
client.socket.transport.websocket.finishClose();
io.server.close();
});
io.server.on('close', function() {
setTimeout( function() {
done();
}, 500);
});
Hope, somebody can help.
The program is waiting because socket.io (server) is still listening for incoming connections. I don't know of any way to stop listening.

Resources