Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js socket.io-client connect_failed / connect_error event

Tags:

I am playing around with node.js and socket.io-client. I am trying to connect to a channel that does not exist in order to trigger the event 'connect_failed' (as specified at https://github.com/LearnBoost/socket.io-client ).

However I can't get the event working:

var clientio = require('socket.io-client');
console.log('Trying stuff ...');

// the channel does not exist
var socket = clientio.connect( 'http://localhost:4000/news' );

// I expect this event to be triggered
socket.on('connect_error', function(){
    console.log('Connection Failed');
});
socket.on('connect', function(){
    console.log('Connected');
});
socket.on('disconnect', function () {
  console.log('Disconnected');
});
socket.send('hi there');

If I execute will this will happen:

$ node tmp_clientio.js 
Trying stuff ...

Any ideas about how to trigger an error if connecting to a channel that does not exist?

UPDATE: Renamed connect_failed to connect_error

like image 769
Tk421 Avatar asked Dec 21 '11 10:12

Tk421


People also ask

How do I fix WebSocket connection failed?

Solution 1Check that all the Bot Insight services are running. Check that your firewall settings are configured to accept incoming websocket data. Try to use a different web browser. Restart the Bot Insight Visualization and Bot Insight Scheduler services.

Does Socket.IO reconnect after disconnect?

Socket disconnects automatically, reconnects, and disconnects again and form a loop. #918.

How do I connect Socket.IO to front end?

You need to pass your server there, not the http module and you need to assign the result to an io variable. So, after you've defined and initialized your server variable, you would do: const io = require("socket.io")(server);


4 Answers

I ran into the same issue. There is a un-documented difference between namespace mode on and off that I also ran into, in the end I had to use the chrome debugger to work it out.

// Bind to the news namespace, also get the underlying socket var ns_news = clientio.connect( 'http://localhost:4000/news' ); var socket = ns_news.socket 

So, you see above that you have to get the actual socket ns_news.socket from your namespace if you want to bind "socket level" events such as connect failed, disconnect, etc

// Global events are bound against socket socket.on('connect_failed', function(){     console.log('Connection Failed'); }); socket.on('connect', function(){     console.log('Connected'); }); socket.on('disconnect', function () {   console.log('Disconnected'); });   // Your events are bound against your namespace(s) ns_news.on('myevent', function() {     // Custom event code here }); 

Note that you now use ns_news to send or receive events

ns_news.send('hi there'); 

Finally, be sure to bind the socket.on('error', ...) event as well - it occurs if the port wasn't available

Full implimentation of 8080 connect with fallback to port 80

I did this in my implementation (try port 8080, if that fails, try port 80 through nginx)

socket_port = 8080;  ns_dash = io.connect("http://your.gridspy.co.nz/dash", {   port: socket_port,   'connect timeout': 5000,   'flash policy port': 10843 });  socket = ns_dash.socket;  try_other_port = function() {   if (socket_port !== 80) {     if (typeof console !== "undefined" && console !== null) {       console.log("Trying other port, instead of port " + socket_port + ", attempting port 80");     }     socket_port = 80;     socket.options.port = socket_port;     socket.options.transports = ['htmlfile', 'xhr-multipart', 'xhr-polling', 'jsonp-polling'];     return socket.connect();   } else {     return typeof console !== "undefined" && console !== null ? console.log("No other ports to try.") : void 0;   } }; socket.on('connect_failed', function() {   if (typeof console !== "undefined" && console !== null) {     console.log("Connect failed (port " + socket_port + ")");   }   return try_other_port(); }); socket.on('error', function() {   if (typeof console !== "undefined" && console !== null) {     console.log("Socket.io reported a generic error");   }   return try_other_port(); }); 

I also added an nginx proxy_pass rule, which looks like this

location ~ ^/(socket.io)/ {     proxy_pass http://127.0.0.1:8080;     proxy_http_version 1.1;     proxy_set_header Host $http_host;     proxy_set_header Upgrade $http_upgrade;     proxy_set_header Connection $connection_upgrade; } 

The Upgrade and Connection options here (from more recent versions of nginx) are required to upgrade the connection between nginx and socket.io to support websockets. That means that your webserver can support websockets on port 80.

Furthermore if your server supports ssl / https, this will proxy wss which is the secure version of websockets.

like image 141
Tom Leys Avatar answered Oct 18 '22 07:10

Tom Leys


they changed the event name. use

reconnect_error 

or

connect_error 

instead

https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L27

like image 26
Soyoes Avatar answered Oct 18 '22 07:10

Soyoes


From the documentation:

connect_failed

Fired when the connection timeout occurs after the last connection attempt. This only fires if the connectTimeout option is set. If the tryTransportsOnConnectTimeout option is set, this only fires once all possible transports have been tried.

So this event fires only if the connectTimeout option is set (the implementation for that is here: https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L223-245 ).

So what you should do different in your code is:

io.connect('http://localhost:4000/news', { 'connect timeout': 5000 }); 
// set connect timeout to 5 seconds
like image 35
alessioalex Avatar answered Oct 18 '22 07:10

alessioalex


This applies to version 1.4.5 (might work on previous versions also).

What you want to do is listen for the "error" event on the socket.io client. It will trigger this event, and the error message will be "Invalid namespace".

Here's an example of how to handle it from the socket.io client:

  var ioclient = require('socket.io-client');
  var websocket = ioclient('http://myserverurl.com/namespacethatdoesntexist');

  websocket.on('error', function(err){
    if (err == 'Invalid namespace') {
      console.warn("Attempted to connect to invalid namespace");
      //handle the case here...
    } else {
      console.warn("Error on socket.io client", err);
    }
  });
like image 22
Eugene Avatar answered Oct 18 '22 08:10

Eugene