This may be a stupid question, but i am wondering if there is a way to force socket.io to periodically retry to use websocket as transport instead of polling?
I noticed that sometimes my application cannot establish a websocket connection (Handshake failed: ERR_CONNECTION_RESET). Socket.io correctly falls back to polling then, but it never seems to try to switch back to websockets again, even if it would work. Is my observation correct?
If so, what would you suggest?
Please let me know if you need any code. I couldn't really think of a relevant code example, since this is more like a theoretical question.
Socket.io correctly falls back to polling then, but it never seems to try to switch back to websockets again, even if it would work. Is my observation correct?
Yes, correct.
If so, what would you suggest?
I dont think its a job of a lib to try to reastablish connection. You can set your own listener, that checks server availability - some times servers crash and users wont notice that they dont have connection anymore...
Kinda example of what we have on client side, hope it helps digging.
//If sockets close
window.ws.onclose = function (e) {
ws.onclose = null;
ws.onerror = null;
ws.onopen = null;
// restart sockets in: 3000 ms
setTimeout(function () { ctx.createWS(); }, 3000);
};
window.ws.onerror = function (error) {
//On error we will try to restart sockets in function described before
ws.close();
};
Related
I am trying to receive private meesages from SocketIO stream. I have IP address but I am getting problem in connection. Also, if connection will happen then also I have to authorize the connection using token then only I can get the messages. I dont how to implement this as I am vey much New to this thing.
I have tried with the following code from the stack overflow but no luck yet.
Also, can anybody tell me which library is best to use:
SocketIO4Net.Client
SocketIOClientDotNet
I am using 2nd one.
var socket = IO.Socket("myip");
socket.On("xx", async (data) =>
{
var test = await Update(data.ToString());
});
Can anybody help me on this. I am .net server side developer.Thanks in advance!!
We're using RabbitMQ + StompJS (w/ SockJS & Spring Websocket as middleware, FWIW) to facilitate broadcasting messages over websockets. Everything is working great, except no matter what we try StompJS creates the Queues as non-auto-delete, meaning we end up with TONS of queues.
We're working around it right now with a policy that cleans out inactive queues after several hours, but we'd rather just have auto-delete queues that terminate after all clients disconnect.
We've attempted setting headers auto_delete, auto-delete, autoDelete and every other possible incantation we can find.
If we stop an inspect the frames before they're transmitted (at the lowest possible level in the depths of StompJS's source) we can see those headers being present. However, they don't seem to be making it to RabbitMQ (or it just doesn't look at them on the "SUBSCRIPTION" command??) and creates them as non-auto-delete.
Interestingly, if we create the queue manually beforehand as auto-delete, the StompJS registration calls error out because the requested SUBSCRIBE expected non-auto-delete. This suggests that it's StompJS (or SockJS) that explicitly state non-auto-delete, but we've poured over the source and ruled that out.
So, the million dollar question: how can we have auto-delete queues with StompJS? Please, pretty please, and thanks in advance :)
Example registration
function reg(dest, callback, headers){
stomp.subscribe(dest, callback, headers);
}
function cb(payload){
console.log(JSON.parse(payload.body));
}
reg('/queue/foobar', cb, {});
Setup details
RabbitMQ 3.5.2 and StompJS 2.3.3
** Note **
If I subscribe directly to the exchange (with destinations like /exchange/foo or /topic/foo) the exchange will be defined as auto-delete. It's only queues that aren't auto-delete.
I'm using StompJS/RabbitMQ in production and I'm not seeing this issue. I can't say for sure what your problem is, but I can detail my setup in the hope you might spot some differences that may help.
I'm running against Rabbit MQ 3.0.1.
I'm using SockJS 0.3.4, I seem to recall having some issues using a more recent release from GitHub, but unfortunately I didn't take notes so I'm not sure what the issue was.
I'm using StompJS 2.3.4
For reasons I won't go into here - I've disabled the WebSockets transport, by whitelisting all the other transports.
Here's some simplified code showing how I connect:
var socket = new SockJS(config.stompUrl, null, { protocols_whitelist: ['xdr-streaming', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'] });
var client = Stomp.over(socket);
client.debug = function () { };
client.heartbeat.outgoing = 0;
client.heartbeat.incoming = 0;
client.connect(config.rabbitUsername, config.rabbitPassword, function () {
onConnected();
}, function () {
reconnect(d);
}, '/');
And here's how I disconnect:
// close the socket first, otherwise STOMP throws an error on disconnect
socket.close();
client.disconnect(function () {
isConnected = false;
});
And here's how I subscribe (this happens inside my onConnected function):
client.subscribe('/topic/{routing-key}', function (x) {
var message = JSON.parse(x.body);
// do stuff with message
});
My first recommendation would be to try the specific versions of the client libs I've listed. I had some issues getting these to play nicely - and these versions work for me.
It is possible with RabbitMQ 3.6.0+ by setting auto-delete in subscribe headers to true. Please see https://www.rabbitmq.com/stomp.html#queue-parameters for details.
How can I disconnect/close all sockets on server side ?
Maybe restarting the socket.io module from the server side ?
(using the lateste socket.io)
Unfortunately, socket.io does not have a publicly documented interface that has been the same from one version to the next to do such a basic function as iterate all connected sockets. If you want to follow the entire history of various ways to do this, then you can follow the whole version history in this question: Socket.IO - how do I get a list of connected sockets/clients?, but you have to pay attention only to answers that apply to specific socket.io versions you are using and then test them for your specific version.
As of Aug 2018, attempting to use only documented interfaces in socket.io, one could use either of these to get a list of connected sockets and then just iterate over them to disconnect them as shown above:
function getConnectedSockets() {
return Object.values(io.of("/").connected);
}
getConnectedSockets().forEach(function(s) {
s.disconnect(true);
});
Depending upon the client configuration, the clients may try to reconnect.
You could also just maintain your own connect socket list:
const connectedSockets = new Set();
io.on('connection', s => {
connectedSockets.add(s);
s.on('disconnect', () => {
connectedSockets.delete(s);
});
});
function getConnectedSockets() {
return Array.from(connectedSockets);
}
getConnectedSockets().forEach(function(s) {
s.disconnect(true);
});
If you are using an older version of socket.io (particularly before v1.4), you will have to either test this to make sure it works in your older version or follow the version history in the above mentioned reference and find an answer there that targets your specific version of socket.io.
For me, jfriend00's solution didn't work (as of today).
I had to do this:
Object.keys(io.sockets.sockets).forEach(function(s) {
io.sockets.sockets[s].disconnect(true);
});
I downloaded the red5-recorder (http://www.red5-recorder.com/) , which fails to allow me to start recording. After debugging I found that the netconnection, needed to record to a media server, created does not fire a NetStatusEvent event, so essentially it fails silently. I have implemented the connection with the following minimal working example:
trace("make net connection");
nc = new NetConnection();
nc.client = { onBWDone: function():void{ trace("bandwidth check done.") } };
trace("add event listener");
nc.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent) {
trace("handle");
});
trace("connect!");
nc.connect("rtmp://localshost/oflaDemo/test/");
trace("connect done");
The output of this piece of code is:
make net connection
add event listener
connect!
connect done
The actionscript api states that the connect-call always fires such an event:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetConnection.html#includeExamplesSummary
Moreover, the netconnection is not 'connected' (a state of the NetConnection object) 10 seconds after the call. I also took a look at this: NetConnect fails silently in Flash when called from SilverLight But the fix suggested by the author, swapping rtmp and http in the connection uri, do not work. Also, I tested the uri and in fact the exact same code sniplet in a personal project, where it did work. I just can not seem to find why connecting to a media server fails silently in the red5-recorder project.
The awkward part is that if I pass some random string as a conenction uri, still nothing happens (no event, no exception, no crash). Also not setting nc.client becore nc.connect(), which caused exceptions in my experience, did not cause exceptions.
Any suggestions are welcome.
You are setting the address to localshost instead localhost.
nc.connect("rtmp://localshost/oflaDemo/test/");
Correct address:
nc.connect("rtmp://localhost/oflaDemo/test/");
I have long poll Ajax request. Browser, at least but not last IE doesn't terminate the request at page leaving, so request remains open and active even if a user visits some other site. Say more, a browser can successfully process responses from this connection, although their result go nowhere. General recommendations as call htmlxml connection abort or stop for a window obviously do not work.
So my implementation is adding extra Ajax call on unload to notify server connection holder that page is on leave, so it can send some dummy response and a browser will return the connection to pool of available after. This approach works but looks for me over engineered. Unfortunately I can observe a similar problem with some other programs, like GMAIL, it also does long poll and as result after some reloading it stops working. So if somebody found some good approach to address the problem without switching to short poll or assign connection timeout, then share your solution.
There's an abort() method on IE's XHR which will manually disconnect it.
It's a bit hacky, but you could try something like:
<body onbeforeunload="AbortMyAjax()">
and use that method to abort any active long-polls.
For reference, here's a bit of code from a project of mine:
$this.lp = null;
function _LongPoll() {
$.ajaxSetup({ cache: false });
$this.lp = $.getJSON(m_PollUrl, _LongPollCallback);
}
And in the body beforeunload:
if(!!QueueManager.lp && !!QueueManager.lp.abort) QueueManager.lp.abort('PAGE_CLOSED');