remoteDisconnect socket.io and redis - node.js

I'm trying to implement socket.io with Redis adapter in NodeJs.
Mostly it works, but sometimes I am still getting errors when trying to disconnect / connect sockets, so I think I haven't implement it correctly.
Could someone please explain what is the difference between
socket.disconnect(); and io.of('/').adapter.remoteDisconnect();
If I initialise my io with:
io.adapter(redisIO({
host: config.server.redis.host,
port: config.server.redis.port,
requestsTimeout: config.server.redis.request_timeout
}));
Shouldn't then socket.disconnect(); be aware of using redisIO? If using remoteDisconnect can I still capture socket.on('disconnect', fn) or should remoteDisconnect be called in socket.on('disconnect', fn)?
What happens if client disconnects? How can I propagate it to socket.io cluster?
Any working examples will be appreciated :)
Thanks!

Capture the socket event disconnecting, not disconnect, by then it's too late!
socket.on('disconnecting', () => {
var room_name = sess.id
io.of('/').adapter.remoteDisconnect(room_name, true, err => {
delete socket.rooms[room_name]
socket.removeAllListeners()
})
})

Related

Socket io emit function making new connection every time

I want to made one connection on one emit function at a time in socket io with react and node js, but it is making new connection every time when emit is called from frontend. Is there any solution for this?
Reactjs code:
socket.emit('getMessages', 1000,this.state.userData._id,id);
Nodejs Code:
client.on('getMessages', (interval,sID,rID) => {
try {
//get messages from mongodb
} catch (err) {
console.log(err);
}
client.on('disconnect', () => {
console.log(`Socket ${client.id} disconnected.`);
});
});
I want to get message IDs but every time I am sending new IDs it makes a new connection and sending previous messages as well.
If you want something to only happen once you could use client.once(....).
If you want the server to not listen for the event anymore after it was emitted once you could add client.removeListener('getMessages') at the end of your listener.
Hope this is helpful. Not sure what behaviour your looking for exactly though.

send JSON data to Unity from Node.js

I asked this question on the official forum but I guess I don't have enough rep there to be taken seriously :O
I'm using Unity3D free.
Has anyone used https://www.assetstore.unity3d.com/en/#!/content/21721 with success? This plugin actually came the closest to working (I also tried this and this but they don't work for me).
I contacted the author but haven't got a reply yet, so was wondering if someone had made this work?
(edit: I would like to point out that I don't mind buying some other plugin if you have used it and found it easy/useful to communicate with your Node.js server via SocketIO - so please recommend)
Concretely, here's my problem with it:
I cant find a way to send JSON data to Unity from Node.js as it keeps getting an error.
I tried numerous ways, and this is one of them:
io.on('connection', function(socket){
console.log('a user connected');
var data ='{"email":"some#email.com","pass":"1234"}';
var dataJson = JSON.stringify(data);
console.dir(dataJson);
socket.emit('newResults', dataJson);
console.log('server emited newResults');
socket.on('fromClient', function(data){
console.log("got msg from client");
console.dir(data);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
In Unity3D I use the following function to intercept this:
public void HandleNewResults(SocketIOEvent e){
Debug.Log(string.Format("[name: {0}, data: {1}]", e.name, e.data));
Debug.Log (new JSONObject (e.data));
}
but it crashes (it catches the error signal) at this point with (when debugging is turned on) this message:
SocketComm:TestError(SocketIOEvent) (at Assets/_Scripts/SocketComm.cs:58)
SocketIO.SocketIOComponent:EmitEvent(SocketIOEvent) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:400)
SocketIO.SocketIOComponent:EmitEvent(String) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:392)
SocketIO.SocketIOComponent:OnError(Object, ErrorEventArgs) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:382)
WebSocketSharp.Ext:Emit(EventHandler`1, Object, ErrorEventArgs) (at Assets/SocketIO/WebsocketSharp/Ext.cs:992)
WebSocketSharp.WebSocket:error(String) (at Assets/SocketIO/WebsocketSharp/WebSocket.cs:1011)
WebSocketSharp.WebSocket:Send(String) (at Assets/SocketIO/WebsocketSharp/WebSocket.cs:1912)
SocketIO.SocketIOComponent:EmitPacket(Packet) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:309)
SocketIO.SocketIOComponent:EmitClose() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:299)
SocketIO.SocketIOComponent:Close() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:184)
SocketIO.SocketIOComponent:OnApplicationQuit() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:164)
Can you please shed some light on how to aproach this problem?
I'm using Unity3D free.
But SocketIO needs Unity Pro. If you want to use native .NET sockets.
Unity Pro is required in order to build using .NET sockets. You may
use a replacement package if you don't want to use native sockets.
You can use Good ol' Sockets.It's usable for sockets.
I used such code:
socket.emit('event_name', {"email":"some#email.com","pass":"1234"});
I do not know if it right. The function in unity is:
public void TestBoop (SocketIOEvent e)
{
Debug.Log ("[SocketIO] Boop received: " + e.name + "--" + e.data);
);
}
And output is:
[SocketIO] Boop received: boop--{"email":"some#email.com","pass":"1234"}
Perhaps it does't right at all but the result at least comes to unity
Make these changes:
io.on('connection', function(socket){
console.log('a user connected');
var data ='{"email":"some#email.com","pass":"1234"}';
var dataJson = JSON.stringify(data);
console.dir(dataJson);
console.log('server emited newResults');
socket.on('beep', function(){
socket.emit('boop', {'boop': dataJson});
console.log("got msg from client");
console.dir(data);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
this is will work.

Capture connection events of two socket servers

I know I am overthinking this... but the answer is just not clicking.
I have two servers, one a TCP socket server and the other a SockJS server. I need to combine both of their connection events into one super event:
async.parallel({
tcp: function (done) {
self._tcp = net.createServer(function (sock) {
done(null, sock);
});
},
ws: function (done) {
self._ws = sockjs.createServer(function (sock) {
done(null, sock);
});
}
}, function (err, results) {
// This never gets fired!!!
// But I'd like to do stuff here with both
// socket instances – you know, like piping =)
});
Originally I had the TCP connection nested within the WS connection, but that's proving to be problematic as it requires a rigid connection sequence. What I really need is an event that is fired when both connections have been established and have access to their respective sock instances. Help jogging the brain would be much appreciated!
This might be overly simple - but looking at the sockjs documentation, there isn't a callback function for createServer() - so it's never going to loop back through the callback of your parallel function.
Try just calling done(null, sock); right after you do socket.createServer(); and you should be all set.
Doc: https://github.com/sockjs/sockjs-node

In Socket.IO, is 'heartbeat' an event that can be used to trigger other actions?

This exact code doesn't work, but, I was hoping something like it was:
io.sockets.on('connection', function(socket) {
socket.on('heartbeat', function() {
// Do something here...
});
});
Is something like this possible? I mean, I know I can just make a different function that triggers every, say, 15 seconds using a setInterval:
io.sockets.on('connection', function(socket) {
setInterval(function() {
// Do something
},15000);
});
But since the heartbeat is already running at this interval, why not make use of it?
In any case, any insight would be greatly appreciated.
I think that I see what you're trying to do. There are a few exposed events that you can check here - list of Socket.io events - but there is no "heartbeat" event that you can tap into to fire at a set interval.
You're on the right track with the second piece of code -
setInterval(function() {
socket.emit('heartbeat', someData);
}, 5000);
And on the client side -
socket.on('heartbeat', function(data) {
console.log(data);
})

How can I detect, when the connection of the client gets interrupted in socket.io?

I have a Node.js-Server with a socket.io-connection to a browser-client. sometimes the connection gets interrupted, for example, when I need to restart the server. When that happens, how can the client know this?
Here's an example on how you can achieve that on the client side:
var chat = io.connect('http://localhost:4000/chat');
chat.on('connect', function () {
console.log('Connected to the chat!');
});
chat.on('disconnect', function () {
console.log('Disconnected from the chat!');
});
As you can see, you keep the connection variable and you use connection_variable.on('disconnect', callback_function_here)

Resources