Can I catch the "can't establish a connection" error for a failed websocket connection?
Asked Answered
G

2

18

I need to test if the connection to my websocket server is established or not.

At this time, I CAN connect to the server, but I want to be able to catch the possibility of that server not being reachable, so this question is about what to do when the websocket connection cannot be established or when it times out.

Using just the basic websocket code in Firefox, it will timeout in about 20 seconds and call my error handler. But it will also throw a JavaScript error that (at least for me using Firebug) shows up in the browser. The log then shows:

Firefox can't establish a connection to the server at ws://192.168.0.1/.

What I've tried so far:

  • Prevent the 20 second timeout by adding my own window.timeout that checks if the onopen handler has been called yet or not, but that does not prevent the JavaScript error.
  • Force-close the websocket at the end of my own timeout, but now I get TWO JavaScript errors - the original plus:

    The connection to ws://192.168.0.1/ was interrupted while the page was loading.

  • Adding try {} catch(e) {} to my code, both when connecting the socket and closing it - no change.

Any ideas on how to get websocket errors to not show in the browser?

Glycine answered 7/4, 2014 at 17:53 Comment(3)
Do you only want to prevent the websocket errors from showing or would banning all errors messages be ok? The answer here may be helpful: #7120790Harbaugh
At this time, I'd prefer only to prevent websocket errors - if that is possible at all. If not, I might have to use the option you posted. Thanks!Glycine
Unfortunately I'm not familiar enough with websockets to recommend a way to filter for those errors specifically. Good luck though!Harbaugh
H
8

What i've learnd so far is: you cant :0(

... because this is somewhat browser specific behavior...

  • so the only thing you can do is using callbacks on ws object and pray ...
  • OR just overwrite console.log ;0)

with the code i did however i got rid of some error messages, maybe it'll help ;)

e.g:

  • Chrome won't complain about dead servers and silently try to reconnect..
  • IE 11 still gives script error
  • etc..

A Basic Class to wrap WS : Have a look at callbacks !

/**
 * Socket Class
 */
Client.Source.Network.Socket.Class = new Class({ implements: [Client.Source.Network.Socket.Interface] },function( Host, Port ){

var Configuration = {
    Server: {
        Protocol: 'ws',
        Host: Host,
        Port: Port
    },
    Event: {
        Open: function(){},
        Error: function(){},
        Message: function(){},
        Close: function(){}
    }
};

var Socket = null;

/**
 * @return {string}
 */
var HostUrl = function() {
    return Configuration.Server.Protocol + '://' + Configuration.Server.Host + ':' + Configuration.Server.Port + '/Connection'
};

/**
 * @returns {boolean}
 */
var IsSupported = function() {
    return "WebSocket" in window;
};

this.Open = function() {
    if( IsSupported() ) {
        Socket = new WebSocket( HostUrl() );
        Socket.onopen = Configuration.Event.Open;
        Socket.onerror = Configuration.Event.Error;
        Socket.onmessage = Configuration.Event.Message;
        Socket.onclose = Configuration.Event.Close;
    } else {

    }
};

this.Send = function( Text ) {
    Socket.send( Text );
};

this.Close = function() {
    Socket.close();
};

this.onOpen = function( Callback ) {
    Configuration.Event.Open = Callback;
};
this.onError = function( Callback ) {
    Configuration.Event.Error = Callback;
};
this.onMessage = function( Callback ) {
    Configuration.Event.Message = Callback;
};
this.onClose = function( Callback ) {
    Configuration.Event.Close = Callback;
};

});

Have a look at the Connect() : onError(), onClose() function

/**
 * Network Class
 */
Client.Source.Network.Class = new Class({ implements: [Client.Source.Network.Interface] },function(){

var _Self = this;
var Socket = null;

this.Connect = function( Host, Port ) {
    Socket = new Client.Source.Network.Socket.Class( Host, Port );
    Socket.onOpen(function(){
        _Self.Gui().Create( Client.Module.Client.Gui() );
        Client.Module.Chat.Message('Connected', 'green', 11);
        Client.Module.Audio.Play( 'Client.Resource.Audio.Chat.UserOnline', 0.2 );
    });
    Socket.onMessage( Response );
    Socket.onError(function(){
        Client.Module.Chat.Message('Connection Error', 'red', 11);
    });
    Socket.onClose(function(){
        _Self.Gui().Destroy();
        Client.Module.Chat.Message('Disconnected', 'darkred', 11);
        Client.Module.Chat.Message('Connecting...', 'orange', 11);
        window.setTimeout(function () {
            _Self.Connect( Host, Port );
        }, 2000);
    });
    Socket.Open();
};

this.Request = function( Application, Request, Data ) {
    Socket.Send( JSON.stringify( { Application: Application, Request: Request, Data: Data } ) );
};
var Response = function( Message ) {
    Message = JSON.parse( Message.data );
    Library[Message.Application].Execute( Message.Request, Message.Data );
};

var Library = {};
this.Protocol = function( Application, Callback ) {
    Library[Application] = Callback;
};

var GuiObject = null;
this.Gui = function Gui() {
    if( GuiObject === null ) {
        GuiObject = new Client.Source.Network.Gui();
    }
    return GuiObject;
};
});
Highhanded answered 23/4, 2014 at 15:20 Comment(2)
+1 for your expertise! But please can you explain briefly what the above does? (which are the key lines that trap errors.) (And as a side note, how come the code doesn't contain WebSocket and also doesn't override console as you mentioned to do?)Dressingdown
Thx :) I cut the examples from one of my libraries so it won't work copy/paste, it's just for explaining things.. The first code block is a wrapper class for the websocket object. It calls new WebSocket( HostUrl() ); in this.Open();. The trapping is handled outside, in the second code block, so please have a look at the Socket.onError callback. It doesn't override console because it's not intended to do so.. if errors pop up and not handled by the callback you may override console.log but it kills the browser debug feature, so it's not in there by default ;)Highhanded
C
0

Try this sort of thing:

function send_data(url,data) {
  var json_text = JSON.stringify(data);
  var socket = new WebSocket(url);
  socket.addEventListener("open", (event) => {
    socket.send(json_text);
  })
  socket.addEventListener("message", handle_message);
  socket.addEventListener("error", () => setTimeout(send_data, 2000, url, data));
}

That attempts to reconnect every 2 seconds.

(I am aware this question is old, I found it while debugging this problem, and thought others might benefit from my conclusions.)

Candycecandystriped answered 23/3, 2023 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.