Note: for support questions, please use one of these channels: stackoverflow or slack
invoke a socket.emit inside a socket.on function does not work. (see code below)
socket.on('notification', function (data) {
socket.emit('news', { hello: 'world' });
});
Server side, emit a message from inside a "socket.on" method.
Message sent to client
Could you please provide a failing test case, based on https://github.com/darrachequesne/socket.io-fiddle/tree/master? I am not able to reproduce.
It's working correctly on my machine too. I don't think its a bug.
Please check your configuration again and ensure that you are sending a socket handshake request from client side(the step I always tend to skip), maybe this is the problem.
You can refer this code: https://gist.github.com/raghavgarg1257/8a5af8aaa447b24e345bc20ddea98ba1 (the example is using express, socket.io and es6)
I am having this same issue. I have a simple Node server running socket.io and a couple clients (React apps) listening. I can do socket.emit()
when it is not nested in a socket.on()
, but it fails when it is nested in one. Here is the code for my server:
const app = require('express')()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const port = 5000 || process.env.PORT
io.on('connection', function (socket) {
socket.on('message', function (message) {
console.log(message)
})
socket.on('send:action', function (action) {
console.log(action)
socket.emit('dispatch:action', action)
})
})
server.listen(port, function () {
console.log('Listening on port:', port)
})
socket.emit('dispatch:action', action)
does not emit. But it will console.log the action. In my client I have:
import React, { Component } from 'react'
import io from 'socket.io-client'
export default class SocketHandler extends Component {
constructor () {
super()
this.socket = io('http://localhost:5000')
}
componentDidMount () {
this.socket.emit('message', 'App connected')
this.socket.on('dispatch:action', function (action) {
console.log(action)
})
}
render () {
return <div className='socket_handler' />
}
}
When the component is rendered, it does connect, and the message
is emitted and logged on the server console, but never is a on('dispatch:action')
received. I am new to sockets, so I'm not certain they would come through, but I'm also not seeing any network activity, which makes me think that the failure is in the server's emit, not on my client.
Of note, I'm using the socket.io-client
lib on the client, but I assumed these are compatible. Based on the docs, I haven't found a reason to believe this isn't true.
Hope this helps. Please let me know if there's more I can do to help or if an answer has been found.
To add to this, I have downgraded versions of socket.io back to 1.5.0 and still getting the same issue. I have also tried reconfiguring my server to match the suggestions made by @raghavgarg1257 and it still did not work either. Once again, let me know if there's anything else you'd like me to test or try and reproduce the issue.
If it's helpful, I am using Node 6.9.1, if there's any reason that could affect how this is working.
Adding further, outside of the socket.on
context .emit()
works find, including it's ack
argument. I was able to get the clients and server to complete their loop with ack
s.
Since I noticed that .emit()
returns a socket, I decided to save what's returned from the nested emit and log it out. Sure enough, it's returning a Socket
. So the function is firing, but it is not emitting what I am expecting, given the arguments I am passing in.
I'm beginning to wonder if there's somehow a transformation of the eventName while in this context.
One last thing, sorry to bombard this thread, just want to add all I've learned. Using socket.broadcast.emit()
does work in the nested context.
Since you are firing dispatch:action
only in send:action
event, so it will be fired only when send:action
is fired from client, and currently it is not happening.
Can you please try changing the send:action
event on server to this:
socket.on('send:action', function (action) {
console.log(action);
// proccesor will reach here only when parent event is fired
socket.emit('dispatch:action', "server says:"+ action);
})
and the function componentDidMount
on client side to this:
componentDidMount () {
this.socket.emit('message', 'App connected');
this.socket.emit('send:action', 'Message sent from Client'); // firing `send:action` to eventually fire `dispath:action`
this.socket.on('dispatch:action', function (action) {
console.log(action)
})
}
Sorry that my above code isn't clear. I am actually sending a socket.emit('send:action')
from another client. The server receives the 'send:action' event and should emit the dispatch:action
event. I can confirm that my client is emitting properly and that my server is responding, as I mentioned the console.log(action)
is working, but the nested socket.emit()
is not.
I know this thread is old but i am currently working this socket.io and i just understoud the problem.
I figure out that what I was trying was to emit an event with a dynamic name using an email address.
This works maching the pattern [a-zA-Z]
but not with "@" or "."
It was to send data to a specific client identified by its email address. Maybe not the properly way to do that.
I solved my issue by switching to primus and using primus rooms.
@Ctaque I'm not able to reproduce either (https://github.com/darrachequesne/socket.io-fiddle/tree/mail-as-room). Could you please provide more details?
Regarding the initial issue: https://github.com/darrachequesne/socket.io-fiddle/tree/answer
@darrachequesne I just tried and it works now. I must have made a mistake before.
I think this thread can be closed. Sorry to waste your time
@Ctaque you're not wasting anyone's time. I'm facing the same trouble. What exactly did you fix to make this work?
Not sure that problem has been resolved but I'm facing the same issue here. My code is pretty similar to @kyleshevlin , and it logs on the server side but it does not on the client side. However, it works after I put socket.broadcast.emit
.
What is going on here?
I never solved this and have left the job where I faced this issue, so I'm unable to reacquaint myself with the problem or provide any context. I just went with the broadcast
solution, and it worked for my scenario.
use io.sockets.emit('news', message)
instead of socket.emit
const app = require('http').createServer()
const io = require('socket.io')(app)
io.on('connection', function (socket) {
socket.on('broadcast', (message)=> {
const token = socket.request.headers.authorization.replace('Bearer ', '')
if (token !== '12b3c4d5e6f7g8h9i') {
return
}
// socket.emit('news', message) will not work
io.sockets.emit('news', message)
})
})
app.listen(8080)
I just started with socket.io and i have no clue if this is the right way to do this. So perhaps some more seasoned socket.io guru can help us.
Would anyone know if this would work to emit an image on canvas and not just a private chat message. I can get the private chat message to work, but if I try to draw an image in one particular room, it will not even call the function.
This works:
var myroom = 'room' + playerNumber;
socket.join(myroom);
io.sockets.in(myroom).emit('send message', 'for your eyes only');
This does not work. It will not even call the function.
var myroom = 'room' + playerNumber;
socket.join(myroom);
io.sockets.in(myroom).emit('showCard', {x: myPlayers.getX, y: myPlayers.getY, objCard: myPlayers.getobjCard});
showCard function:
var x = data.x + 130;
var y = data.y - 40;
var objCard = new Image();
objCard.onload = function() {
context.drawImage(objCard, data.x+100, data.y);
}
objCard.src = data.objCard;
This thread helped me troubleshoot the same problem, wanting to socket.emit()
from inside a socket.on()
function on a server. Solutions above seem to broadcast to all; the following code seems to limit the message to only the client that triggered the socket.on()
.
socket.on('send:id', id => {
fetch(url/with/id/in/query/param)
.then(response => {
// do stuff with the response, including an io.emit() to all connected clients
io.emit('playlist', videoArray);
})
.catch((e) => {
// send potential catch msg back to the socket that triggered this function
io.sockets.connected[socket.id].emit('err', { message: e });
});
});
I have the same problem, I can not use socket.emit when nested in io.sockets.on, but the emit works perfectly in other conditions. I also tried debugging with a console.log, so I know it is the emit that isn't working.
socket.on('channel1', function(data)
{
console.log(data)
io.emit('channel2', data)
}
my solution and it works fine
Hello,
Excuse me for re-opening this ticket but I have a problem very similar to the one mentioned.
When sending a socket.emit request triggered by a socket.on event, it works most of the time, but after an indefinite time, without any error occurring and without any trace of this one does not respond at all. Request events are sent but there are no more events received in response.
I do not understand this rather random behavior. There are 3200 clients on the websocket in competition but it also happens when there are 800.
I have the same problem as above.
io.socket.emit gives error Cannot read property 'emit' of undefined
my function on client side is simple:
````
const io = require('socket.io-client');
let socket = io('http://localhost:7777');
socket.on("connect", () => {
console.log("Socket zareagowa艂 na po艂膮czenie sieciowe");
socket.emit("startstream");
});
````
on server side
````
io.on("startstream", async socket=>{
console.log("Connecting to the stream");
});
````
that console.log message never appears so either event is not emited or server is not receiving it
Most helpful comment
use
io.sockets.emit('news', message)
instead ofsocket.emit
I just started with socket.io and i have no clue if this is the right way to do this. So perhaps some more seasoned socket.io guru can help us.