I am trying to use callback function on the server when I emit to a room. In the room there is only 1 device that has a specific channel number. I can emit to it but can not get the callback to work.
server
socket.to(userId).emit('request-api', options, (response: any) => {
console.log(response);
});
client
socket.on('request-api', (arg1, callback) => {
console.log(arg1);
callback({
status: 'ok',
});
});
Is there a way that I can have the server to emit event and get callback. Nodejs project
Related
I am making a chatroom application using reactjs(socketIo) and nodeJs. When I emit the message from frontend to server, it gets emitted only once, but when I emit it back from server to frontend, It gets emitted multiple times.
Frontend Code:
function handleChat(event) {
event.preventDefault();
socket.emit("newMessage", { message: msg, user: props.user.name });
setMsg("");
}
socket.on("messageList", (list) => {
console.log(list.message);
var allMsg = messages
allMsg.push({message: list.message.message, name: list.message.user})
setMessages(allMsg);
})
In the code above newMessage is the handler for emitting the message from frontend to server and messageList is the handler for message from the server(which is the issue).
Backend Code:
namespace.forEach((ns) => {
io.of(`/${ns.name}`).on("connect", (socket1) => {
// console.log(ns.name, socket1.id);
socket1.on("name",(name)=>{
console.log(name);
})
socket1.on("newMessage", (message) => {
console.log(message);
io.of(`/${ns.name}`).emit("messageList",{message})
});
});
});
In my MERN app I have the following code:
Server:
io.on('connection', (socket) => {
socket.join('main');
socket.on('start session', function(data){
socket.join('sockets');
});
socket.on('try', () => {
io.in('main').emit('test', 'hi');
io.in('sockets').emit('test', 'hello');
console.dir(socket.rooms);
})
});
Client:
componentDidMount() {
socket.on('connect', function(){console.log('connected to socket')});
socket.on('test', function(data){console.log(data)});
socket.on('event', function(data){console.log(data)});
socket.on('error', (error) => {
console.log(error)
});
}
setSession(id, slug) {
if(!this.state.sessionId) {
socket = io(serverUrl);
this.setState({ sessionId: id, slug: slug });
let sessionInfo = {room: id, slug: slug};
console.log(`Session local init. SessionId: ${id}, Slug: ${slug}`);
socket.emit('start session', sessionInfo);
}
}
In a separate client component I emit the 'try' event when I click a button.
The server console validates that the socket is in both rooms (this is called after we emit the events, so there is no way the socket's rooms are being changed/overwritten)...
{
ub1_9Nw3sMtfZQtBAAAF: 'ub1_9Nw3sMtfZQtBAAAF',
main: 'main',
sockets: 'sockets'
}
...however, the client only receives the event emitted to the 'main' room, and not the 'sockets' room. The server thinks the client is in both rooms and the only difference is that the 'sockets' room assignment is in an event callback and the 'main' room assignment is at the top-level of the 'connection' function. Thoughts?
For now, I've managed to bypass this issue by sending the room name in the query param when the client connects.
Client:
socket = io(serverUrl, {query: {id: id}});
Server:
io.on('connection', (socket) => {
socket.join(socket.request._query.id);
socket.on('try', (data) => {
io.to(data).emit('join', 'bang');
})
});
...however it still seems as if the original code should have worked - very little else has been modified. Leaving the question up because a workaround isn't a solution and this isn't best practice!
You only join the 'sockets' room if the client emits a 'start session' event.
socket.on('start session', function(data){
socket.join('sockets');
});
Client only seems to be emitting 'start session' in setSession, and I don't see that method getting called anywhere.
I'm trying to get status callbacks for various room events, but twilio is not sending any events to my callback URL, I've used the following code to create a room using the documentation i found here
app.get('/createRoom', function (req, res) {
var client = new Twilio(twilioApiKey, twilioApiSecret, {
accountSid: twilioAccountSid
});
client.video.rooms.create({
uniqueName: myRoomName,
statusCallback: 'myCallbackURL'
}).then((room) => {
//
});
});
I'm trying to send news to my client. On connect, it works great, but for some reason on broadcast2 it wont get any response client sided, even know its the same piece of code, and even that broadcast2's console.log is working.
Q: How can i make sure broadcast2 emit will work?
This works:
socket.on('message', function (data) {
console.log('message gotten');
socket.emit('news', { message: 'xxxx' });
});
this wont work:
socket.on('broadcast2', function (data) {
console.log("broadcast revieced");
socket.emit('news', { message: 'xxxx' });
});
this is node.js response:
total code in node.js
socket.on('message', function (data) {
console.log('message gotten');
});
socket.on('another-message', function (data) {
socket.emit('not-news', { hello: 'world' });
});
socket.on('broadcast2', function (data) {
console.log("broadcast revieced");
socket.emit('news', { message: 'xxxx' });
});
and this on the client side:
var socket = io.connect('mysite:8080');
function sender() {
console.log('sending tester');
socket.emit('sendertester', 2);
}
socket.on('connect',function(){
});
socket.on('tester', function(msg){
console.log("callback");
});
socket.on('news', function(message) {
console.log("INCOMMING NEWS");
console.log(message);
});
UPDATE 1:
The broadcast2 socket, sent by PHP:
function broadcast($message,$broadcast = 'broadcast2') {
$client = new Client(new Version1X('myurlhidden:8080'));
$client->initialize();
$client->emit($broadcast, ['message' => $message]);
$client->close();
}
UPDATE 2:
**Question two: Cause my broadcast2 is sent before the client sided is loaded, and then the client connects to the node, could that be the cause?
But in the same time, im already preloading the class that holds the broadcast2 emitter.
Using codeigniter framework.**
UPDATE 3
I was trying to check my theory on update 2, by having two users logged in, while user one trying to perform the trigger. user two gets no output, so i suppose that theory is busted.
The server cannot send a message to any socket before it is connected. You have to wait until you have something listening to receive what you are sending.
I wouldn't call close after the emit either, as you may close the connection before the client has received the message, emit doesn't wait for the client to receive the data before returning its asynchronous.
Instead let the clients close the connections when they terminate.
My server emits events properly, but the emit callback never works. In the following, nothing is logged on my console:
Server:
io.sockets.emit('delete hint', {id: id}, function(data){
console.log('callback');
});
Client:
socket.on('delete hint', function(data){
// display a message before deleting
$('#' + data.id).fadeOut(function(){
$(this).remove();
});
});
I've also tried the client side code as function(data, fn) in case the callback needed to be included on the receiving function.
I'm using windows and my command prompt shows the following when socket.io is emitting the event:
websocket writing 5:::{"name":"delete hint", "args":[{"id":"1"}, null]}
I can't figure out what the problem is, what am I doing wrong?
A callback is executed on the sender computer when the receiver computer calls it
Have a look at this code:
Server:
io.sockets.on('connection', connectionFunc);
function connectionFunc (socket) {
socket.emit('delete hint', "data for client", callThis);
}
//this function is executed when client calls it
function callThis (dataFromClient){
console.log("Call back fired: " + dataFromClient);
}
Client:
socket.on('delete hint', function(data, callback) {
console.log("i received: "+ data);
// call back will fire only when u the next line runs
callback("the callThis function on server will run");
});
You can do this the opposite way.
You need to call the callback.
socket.on('delete hint', function(data, cb){
// display a message before deleting
$('#' + data.id).fadeOut(function(){
$(this).remove();
cb(null, 'done');
});
});