How to disconnect all sockets serve side using socket.io? - socket.io

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);
});

Related

Parse.Config does not work on Parse Server?

I can't seem to find anything official about this: Does Parse.Config work on Parse Server? It used to work on Parse.com but when I try to migrate to Parse.Server, when trying the REST API it seem to fail:
GET http://localhost:1337/parse/config
Passing in my app ID. I read somewhere Config does not work on Parse Server, but wanted to confirm
Although is not officially supported as mentioned on the docs,there is a way to make it work. It is still an experimental implementation though.
As mentioned here & here, you should set the environment variable:
PARSE_EXPERIMENTAL_CONFIG_ENABLED=1
Then restart your node server. In case you deployed it on heroku for example you should on cli heroku restart -a <APP_NAME>
If that doesn't work I would suggest to simply add your route with your configuration options on your project's index.js file where express is initialized like so.
var parseConfig = {
"params": { /*...put your options here*/ }
};
// :one? is for old SDK compatibility while is optional parameter.
app.all('/parse/:one?/config', function (req, res) {
res.json(parseConfig);
});

stompjs + rabbitmq - create Auto-Delete queues

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.

Is there a way to make Dart server websocket implementation compatible with Phantom 1.9.7 headless browser (another websocket standard that is)?

According to the WebSocketTransformer docs, it says it tries to upgrade HttpRequests according to the RFC6455 web socket standard:
This transformer strives to implement web sockets as specified by RFC6455.
And provides this Dart example code:
HttpServer server;
server.listen((request) {
if (...) {
WebSocketTransformer.upgrade(request).then((websocket) {
...
});
} else {
// Do normal HTTP request processing.
}
});
Now if you search through PhantomJS' issue tracker you can find issue:
11018 Update to final websocket standard
Which basically says that the latest PhantomJS (1.9.7) uses an old web socket standard (I still haven't figured out what version sends out the Sec-WebSocket-Key1 information, but I assume its not the RFC6455 version).
So basically, my problem is that when I run PhantomJS headless browser towards my site that uses Dart 1.3.3, websocket server implementation (basically some upgrade code as I pasted above), it says:
Headers from PhantomJS:
sec-websocket-key1: 327J w6iS/b!43 L2j5}2 2
connection: Upgrade
origin: http://mydomain.com
upgrade: WebSocket
sec-websocket-key2: 42 d 7 64 84622
host: mydomain.com
Dart:
WebSocketTransformer.isUpgradeRequest(request) = false
WebSocketException: Invalid WebSocket upgrade request
The upgrade of the request failed (I assume it because of the mis match of versions).
My question is, until Phantom JS gets updated with 2.0, is there a way I can fix my Dart back-end so it would handle PhantomJS websockets as well?
According to the docs of WebSocketTransformer, the upgrade function has two arguments, one HttpRequest mandatory, and a second optional argument:
static Future<WebSocket> upgrade(HttpRequest request, {Function protocolSelector(List<String> protocols)})
Could this maybe help me some how?
The protocols won't help you. These allow to agree on a special protocol that is used after the handshake for communication. But you can't modify the handshake and the exchanged fields themselves.
What you could do is make a complete own websocket implementation (directly based on Dart HTTP and TCP) that matches the the old implementation that PhantomJS uses. But that won't work with newer clients. By that way you also might be able to make an implementation that supports several versions (by checking the headers when you receive the handshake HTTP request and depending on the handshake forward to another implementation.
You would have to do at least your own WebSocketTransformer implementation. For this you could start by copying Darts interface and implementation and modify it on all places you need (check Licenses). If the actual WebSocket behavior after the handshake is compatible in the two RFCs you could reuse Darts WebSocket class. If this is not the case (other framing, etc.) then you would also have to do your own WebSocket class.
Some pseudo code based on yours:
HttpServer server;
server.listen((request) {
if (...) { // websocket condition
if (request.headers.value("Sec-WebSocket-Key1") != null) {
YourWebSocketTransformer.upgrade(request).then((websocket) {
... // websocket might need to be a different type than Dart's WebSocket
});
}
else {
WebSocketTransformer.upgrade(request).then((websocket) {
...
});
}
}
else {
// Do normal HTTP request processing.
}
});
I don't know your application, but it's probably not worth the effort. Bringing the old websocket implementation into Dart is probably the same effort as bringing the official implementation to PhantomJS. Therefore I think fixing PhantomJS should be preferred.
"No."
HttpRequest.headers is immutable, so you can't massage the request headers into a format that Dart is willing to accept. You can't do any Ruby-style monkey-patching, because Dart does not allow dynamic evaluation.
You can, should you choose a path of insanity, implement a compatible version of WebSockets by handling the raw HttpRequest yourself when you see a request coming in with the expected headers. I believe you can re-implement the WebSocket class if necessary. The source for the WebSocket is here.
Maybe it's possible to do that through inheritance. It's impossible in dart to avoid overriding.
If you have the time and you really need this, you can re-implement some method to patch the websocket for PhatomJS
class MyWebSocket extends WebSocket {
MyWebSocket(/* ... */) : super(/* ... */);
methodYouNeedToOverride(/* ... */) {
super.methodYouNeedToOverride(/* ... */)
// Your patch
}
}
This way will allow you to access to "protected" variable or method, may be useful for a patching
But be careful, WebSocket are just the visible part, all the implementation is in websocket_impl.dart

Problems with online visitor tracking

I am working with web-socket project. We are tracking the customers of the website and showing that information to our customers dashbaord.
For this we are using pubnub service. They have api to subscribe and her_now to get currenly active connections. But seems it is not working properly. It is not tracking as we expecting.
It is not sending events properly when customers have lot of traffic(>150 active). And even his cost is too high.
We are planning to move to some other technique to do this. Please suggest which one is the good option.
How about nodejs with socket.io. One thing i am thinking the scalability when our customers have lot of traffic.
Please suggest on this.
Thanks,
Govind.
Move to Socket.io (It,s support mobile and all browser) and performance is good
Problems with online visitor tracking:
Here is my answer,When user visit you website you emit some event using following code
Server side:
var io = require('socket.io');
io.sockets.on('connection', function (socket) {
//From user
socket.on('userEnterYourWebsite',function(data){
//Do some DB operation means retrive user related information from DB
//If emit some data to user
socket.emit('sendToUser',{name:'mmm',state:'tamilnadu'});
});
});
Client Side:
<script>
var socket=io.connect('http://ipaddress:8080');
var userIDorUniqueID='mmmmmmm';
socket.emit('userEnterYourWebsite',{uniqueID:userIDorUniqueID});
//From server
socket.on('sendToUser',function(data){
console.log(data.state);
});
</script>
Property Annouce Max
You just need to set the Presence Announce Max property on the Presence add-on higher. Contact support#pubnub.com to set it higher than 100.
Build vs. Buy
What will be the cost of scaling your DIY node/socket.io solution? See the following before considering the DIY route.
http://www.pubnub.com/blog/build-vs-buy-why-diy-isnt-always-better/
http://www.pubnub.com/customers/swaplingo/
http://www.pubnub.com/customers/tint/

WebSockets + Haxe?

I need to develop an application using WebSockets and Haxe.
I came upon this lib: http://lib.haxe.org/p/hxWebSockets
But it's outdated.
Then I found this blog post: http://bp.io/post/322
But the links to the code are broken :(
So, anyone out there knows any other WebSocket resource for Haxe?
If not, does someone has a clue where to start looking to start implementing my own solution?
Thanks!
If you use node.js as a platform, I'd recommend you to make bindings to socket.io. If you use another platform, I'd recommend to use socket.io as a reference implementation, or just port it to haxe, which shouldn't be that hard.
The lib you mentioned is indeed outdated. Luckily, someone made a new one, supporting the latest websocket protocol:
http://lib.haxe.org/p/WebSocket
...however, it's still a bit lower level than nodejs/socket.io
I am using haxe for a websockets application and using the js libraries:
import js.html.WebSocket;
Using the following function to connect to the server.
private function connect() {
trace("Calling connect");
try {
websocket = new WebSocket(connectionString());
websocket.onclose = onClose;
websocket.onerror = onServerConnectionError;
var openStream = initializeElementStream(cast websocket, "open");
openStream.then(onOpen);
var eventStream = initializeElementStream(cast websocket, "message");
eventStream.then(onMessage);
var closeStream = initializeElementStream(cast websocket, "close");
closeStream.then(onClose);
var errorStream = initializeElementStream(cast websocket, "error");
errorStream.then(onServerConnectionError);
}catch(err : Dynamic) {
trace("Error establishing connection " + err);
}
trace("Connection successful");
}
Will this work for you. I am sticking to standard js libraries for my project. This has worked for me since the project has no external dependencies.
I recently started using Haxe-Js-Kit and it has decent bindings for a lot of nodejs libs including Socket.IO.
https://github.com/clemos/haxe-js-kit/
Make sure you use the dev branch for development as it is quite more advanced than the haxelib or master branch.

Resources