jmesnil / stomp-websocket

Stomp client for Web browsers and node.js apps
http://jmesnil.net/stomp-websocket/doc/
Apache License 2.0
1.43k stars 588 forks source link

Connect fails silently if server is not available using Node and Stomp.overWS(...) #102

Open techniq opened 9 years ago

techniq commented 9 years ago

When using Node and the websocket API (Stomp.overWS('ws://...'), if the server is unavailable (service is down, wrong URL, etc), client.connect(...) fails silently (neither success or failure callback is called). I looked into the bundled WebSocket client and it appears it has a connectFailed event for these situations:

client.on('connectFailed', function(error) {
    console.log('Connect Error: ' + error.toString());
});

I've ran into this issue on a project where I will reboot the server and expect the clients to reconnect, but they hang on the next client.connect(...) call while the server is starting back up. I think it would be best if the event was watched and an error thrown (or the failure callback is called):

client.on('connectFailed', function(error) {
    throw error
});

Somewhat related, It would also be nice if a custom WebSocket library could be used in place of the theturtle32/WebSocket-Node one (like stomp's browser API allows). For example, using the popular einaros/ws library:

var Stomp = require('stompjs');
var WebSocket = require('ws');
var ws = new WebSocket('ws://echo.websocket.org');
var client = Stomp.over(ws)

This library matches the W3C spec more closely and will throw an exception while creating an instance of WebSocket, just like the browser does. Note: theturtle32/WebSocket-Node has a W3CWebSocket API, but it does not throw an exception while creating an instance of W3CWebSocket

var W3CWebSocket = require('websocket').w3cwebsocket;
var client = new W3CWebSocket('ws://localhost:8080/'
techniq commented 9 years ago

FYI, I worked around the issue by using popular einaros/ws library and listening to setting up a handler for the onerror callback.

var WebSocket = require('ws');

WebSocket.prototype.onerror = function(e) {
    throw e
};

var ws = new WebSocket(config.uri);
client = Stomp.over(ws);

My actual implementation wraps all of this in a Promise (and I reject the promise within the onerror), but this should help someone else who runs into this issue.