What's the difference between these two?
I noticed that if I changed from socket.emit to socket.send in a working program, the server failed to receive the message, although I don't understand why.
I also noticed that in my program if I changed from socket.emit to socket.send, the server receives a message, but it seems to receive it multiple times. When I use console.log() to see what the server received, it shows something different from when I use socket.emit.
Why this behavior? How do you know when to use socket.emit or socket.send?
With socket.emit you can register custom event like that:
server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
client:
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
Socket.send does the same, but you don't register to 'news' but to message:
server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.send('hi');
});
client:
var socket = io.connect('http://localhost');
socket.on('message', function (message) {
console.log(message);
});
Simple and precise (Source: Socket.IO google group):
socket.emit allows you to emit custom events on the server and client
socket.send sends messages which are received with the 'message' event
TL;DR:
socket.send(data, callback) is essentially equivalent to calling socket.emit('message', JSON.stringify(data), callback)
Without looking at the source code, I would assume that the send function is more efficient edit: for sending string messages, at least?
So yeah basically emit allows you to send objects, which is very handy.
Take this example with socket.emit:
sendMessage: function(type, message) {
socket.emit('message', {
type: type,
message: message
});
}
and for those keeping score at home, here is what it looks like using socket.send:
sendMessage: function(type, message) {
socket.send(JSON.stringify({
type: type,
message: message
}));
}
socket.send is implemented for compatibility with vanilla WebSocket interface. socket.emit is feature of Socket.IO only. They both do the same, but socket.emit is a bit more convenient in handling messages.
In basic two way communication systems, socket.emit has proved to be more convincing and easy to use (personal experience) and is a part of Socket.IO which is primarily built for such purposes
https://socket.io/docs/client-api/#socket-send-args-ack
socket.send // Sends a message event
socket.emit(eventName[, ...args][, ack]) // you can custom eventName
Related
here's the init of the redis pubClient and subClient
onConnection event with socket
i'm trying to initialize the redis in every socket connection :
this.subClient.psubscribe(this.channel + "*", onError);
TypeError: this.subClient.psubscribe is not a function
As TJ mentioned, inline code would be much, much better. You should revise your question to include that. That said, I looked at your code and I see two problems.
You haven't opened your Redis connect. Instructions on how to do this can be found at the top of the README for Node Redis. I've pasted it below for your convenience, but you'll want to go over the README for more details:
import { createClient } from 'redis';
const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
The method is pSubscribe not psubscribe. Examples for Redis Pub/Sub are also in the README, albeit a bit further down. Here's the salient bits:
const subscriber = client.duplicate();
await subscriber.connect();
await subscriber.pSubscribe('channe*', (message, channel) => {
console.log(message, channel); // 'message', 'channel'
});
await subscriber.pUnsubscribe('channe*');
Hope this helps and, please, help future readers by inlining your code. Thanks!
I'm getting comfortable with socket.io. It really rocks.
I am aware that from the server, I can either:
Respond to a socket client:
socket.emit(event, data);
Broadcast to other clients:
socket.broadcast.emit(event, data);
Broadcast to all clients without distinction:
io.emit(event, data);
But what I'd like to do is to loop over the clients to emit to each of them, with their socket.id as a parameter:
io.emitEach(socket => socket.emit(event, dataWichDependsOn(socket.id)));
Can I achieve this?
I tried this:
io.of('/').clients((error, clients) => {
if (error) throw error;
return clients.forEach(clientId => {
io.to(clientId).emit(event, dataWichDependsOn(clientId));
})
}
Without success :( the message doesn't seem to be emited.
Object.keys(io.sockets.sockets).forEach((clientId)=>{
io.to(clientId).emit(event, dataWichDependsOn(clientId))
})
I'm running into an issue with my socket.io implementation and don't know how to solve it. I'm using pg_notify with LISTEN so when a certain value is modified in the db, it emits 'is_logged_in' to a certain client.
That in itself is working fine - my issue is when I refresh the page, socket.io disconnects the current socket_id, creates a new socket_id as usual, but when this happens, it's creating a second pgsql client instance and duplicating requests - fires the "logged_in" event 2x.
If I refresh the page again, and then manually fire the pg "logged_in" trigger, it will now emit 3 times etc. I have a leak.
const io = require('socket.io')();
const pg = require('pg');
io.on('connection', (socket) => {
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect()
pgsql.query("LISTEN logged_in");
pgsql.on('notification', function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
});
socket.on('disconnect', () => {
//pgsql.end();
});
});
I've tried killing the pgsql instance (in the socket.on disconnect) but for some reason the LISTEN stops working when I do that.
I've also tried moving the new pg.Client outside the io.on connection but when I refresh the page, the old socket_id disconnects, the new one connects, and it never executes the code to recreate the pg client.
Any ideas?
These are creating problems probably:
The pgsql instance is created on each socket connection request and is not being destroyed on disconnection
notification handler is not being removed on disconnection
I'm not much familiar with postgres, but I have worked extensively with socket. so, something like this should fix your issue:
const io = require('socket.io')();
const pg = require('pg');
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect();
io.on('connection', (socket) => {
pgsql.query("LISTEN logged_in");
const handler = function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
// You could also do pgsql.off('notification', handler) here probably
// or check if pgsql.once method is available as we need to call this handler only once?
}
pgsql.on('notification', handler);
socket.on('disconnect', () => {
pgsql.off('notification', handler);
//pgsql.end(); // Call it in server termination logic
});
});
Is there any way to know socket io emit failed and success, something like ajax callback methods: onSuccess, onError?
For socket io emit i only find:
socket.emit('publish', {message:'test message'},function (data) {
alert("")})
This callback only be called when the server send an ack response.But it can not apply for this situation:
At the moment of emit message to server, there is bad network or lost connection, that means server not receive this message, so the client callback function is not called.
What I want is:
When I call the socket io emit, if it fails, I want to retry 3 times.
I know this is an old post, but just in case anyone is still having trouble with this.
var socket = new io.connect('http://localhost:3000', {
'reconnection': true,
'reconnectionDelay': 1000,
'reconnectionDelayMax' : 5000,
'reconnectionAttempts': 3
});
socket.on('connect_error', function() {
console.log('Connection failed');
});
socket.on('reconnect_failed', function() {
// fired only after the 3 attemps in this example fail
console.log('Reconnection failed');
});
More info here -> https://socket.io/docs/client-api/#manager-reconnectionAttempts-value
What's the difference between these two?
I noticed that if I changed from socket.emit to socket.send in a working program, the server failed to receive the message, although I don't understand why.
I also noticed that in my program if I changed from socket.emit to socket.send, the server receives a message, but it seems to receive it multiple times. When I use console.log() to see what the server received, it shows something different from when I use socket.emit.
Why this behavior? How do you know when to use socket.emit or socket.send?
With socket.emit you can register custom event like that:
server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
client:
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
Socket.send does the same, but you don't register to 'news' but to message:
server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.send('hi');
});
client:
var socket = io.connect('http://localhost');
socket.on('message', function (message) {
console.log(message);
});
Simple and precise (Source: Socket.IO google group):
socket.emit allows you to emit custom events on the server and client
socket.send sends messages which are received with the 'message' event
TL;DR:
socket.send(data, callback) is essentially equivalent to calling socket.emit('message', JSON.stringify(data), callback)
Without looking at the source code, I would assume that the send function is more efficient edit: for sending string messages, at least?
So yeah basically emit allows you to send objects, which is very handy.
Take this example with socket.emit:
sendMessage: function(type, message) {
socket.emit('message', {
type: type,
message: message
});
}
and for those keeping score at home, here is what it looks like using socket.send:
sendMessage: function(type, message) {
socket.send(JSON.stringify({
type: type,
message: message
}));
}
socket.send is implemented for compatibility with vanilla WebSocket interface. socket.emit is feature of Socket.IO only. They both do the same, but socket.emit is a bit more convenient in handling messages.
In basic two way communication systems, socket.emit has proved to be more convincing and easy to use (personal experience) and is a part of Socket.IO which is primarily built for such purposes
https://socket.io/docs/client-api/#socket-send-args-ack
socket.send // Sends a message event
socket.emit(eventName[, ...args][, ack]) // you can custom eventName