Problems with emitting to all clients with socket.io - javascript

var io = require('socket.io').listen(server1);
io.on('connection', function(io){
socket_call_data = function(some,data){
io.emit("new_peer_data", result);
}
io.on('event', function(data){
//doing stuff
socket_call_data(some,data);
});
});
This is my current code and the problem is that io.emit (in the function socket_call_data) only seems to emit to the user who connected. So, after doing some reading, I used io.broadcast.emit. This worked great, however it does not include the user who connected - who I do also want to be sent the data. So, finally i came to find out about io.sockets.emit which supposedly sends it to all clients. But instead, i get the error:
Missing error handler on `socket`.
TypeError: Cannot call method 'emit' of undefined
at socket_call_data (/var/www/html/live_nodejs/handle.js:47:20)
So io.sockets.emit is not defined...
What am I getting wrong?
Thanks

It looks like you're overwriting your io variable with a single socket when the user connects. Change the io arg on your connection event to socket instead:
var io = require('socket.io').listen(server1);
io.on('connection', function(socket){
socket_call_data = function(some,data){
io.emit("new_peer_data", result);
}
socket.on('event', function(data){
//doing stuff
socket_call_data(some,data);
});
});
Then io.emit() should emit to all sockets.

What is happening is that you are passing io in the function
io.on('connection', function(io){
//Your Code here
});
so, the Global io and the io that you are passing inside the function are becoming ambiguous. All you need to do is, change the io that you are passing inside the function to some other variable like socket or something.
io.on('connection', function(socket){
//Your code here
socket.emit("some event specific to this particular socket");
io.sockets.emit("This event will be broadcasted to everyone connected");
});
This should help you out.

Related

Socket.io—about socket disconnect

I have this scenario with socket.io:
I want to receive the data from a sever and Forward the data to webclient.But when I receive a lot of data and close the page, it console
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
DISCONNECTED FROM CLIENT
...(a lot)
Here is the code:
server:
var express=require('express');
var app=express();
var net=require('net');
var http=require('http').createServer(app);
var io=require('socket.io')(http);
var net=require('net');
var nodeServer = new net.Socket();
var aSocket=null;
io.on('connection', function (socketIO) {
aSocket=socketIO;
};
nodeServer.on('data', function(data) {
if(aSocket!=null){
aSocket.emit('pushToWebClient',useData);
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
}
client:
socket.on('pushToWebClient', function (useData) {
});
I find
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
console a lot of'DISCONNECTED FROM CLIENT' but actually it should console just once in the code.
I had even console.log(aSocket.id),it console just only one.
I don't know why it is console so many times.
I haved used setMaxListeners(10) to try to avoid it .
Will it lead to a memory leak?
It appears that you are registering multiple event listeners for the same disconnect event. In this code:
nodeServer.on('data', function(data) {
if(aSocket!=null){
aSocket.emit('pushToWebClient',useData);
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
}
You appear to be registering a new disconnect event listener every time you get a data message. So, if you have multiple listeners, then each one will get called when the socket disconnects and the result is that you will log the same message multiple times all for the same socket.
You can verify this is what is happening by moving your disconnect handler into the connection handler so it is only ever attached just once for each socket.
In addition putting asocket into a global or module-level variable means that your server code would only ever work with one single client at a time. It is not clear exactly what you are trying to do when you get data on the nodeserver connection - whether you're trying to send that data to only one specific client or to all connected clients.
I try to delete the code:
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
or moving it out of nodeServer handler,
it turn into normal and never suggest me to setMaxlisener.
I think maybe it is incorrect put one API into a API
And the envent maybe not release the socket,so it console multiple times .
EDIT: I'm moving this to the top because I saw that someone already provided my solution but you were having a problem managing the data sent to the client. Your aSocket variable will be overwritten by every new client that connects to your app. If you want to send data to a specific client using your server nodeServer, you should create a global variable (an array) that keeps track of all of your client socket connections. So instead of using one global variable aSocket do the following:
var net=require('net');
var nodeServer = new net.Socket();
var clients = [];
io.on('connection', function (socketIO) {
clients.push(socketIO);
var clientNum = clients.length-1;
aSocket.on('disconnect', function () {
clients.splice(clientNum, 1);
console.log('DISCONNECTED FROM CLIENT: '+socketIO.id);
});
};
nodeServer.on('data', function(data) {
//have your data object contain an identifier for the client that caused the handler to fire
//for the sake of the answer I just use data.id
var clientID = data.id;
if(clients[clientID]!=null){
clients[clientID].emit('pushToWebClient', useData);
}
}
Let me know how it goes! My original answer is below:
Try moving
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
out of your nodeServer.on('data', ...) event listener into the io.on('connection', ...) event listener like so:
io.on('connection', function (socketIO) {
aSocket=socketIO;
aSocket.on('disconnect', function () {
console.log('DISCONNECTED FROM CLIENT');
});
};
socket.io is designed to keep polling for the presence of the server/client. If either the server or the client are disconnected, the remaining 'side' continues to receive polling requests and, consequently, will continuously print an error.
You can see this effect on the client side in your browser when you disconnect your server and leave the client page open. If you look at the browser's error/console log what you should see is a continuous stream of net::ERR_CONNECTION_REFUSED errors. By placing the disconnect event handler in the .on('data', ...) handler for your server, you are seeing the converse of this situation.
net:ERR_CONNECTION_REFUSED example
This is basic code for socket.io
The following example attaches socket.io to a plain Node.JS HTTP
server listening on port 3000.
var server = require('http').createServer();
var io = require('socket.io')(server);
io.on('connection', function(client){
client.on('event', function(data){});
client.on('disconnect', function(){});
});
server.listen(3000);
I think, you should try.

socket io: how to pass paramter to disconnet socket event?

I am using socket io for building a chat app.
when "user x" is disconneting from the chat I want to print to the console log: "bye user x".
for that to happen I need to pass as a paramater the user_name to the disconnect event.
problem is that I don't know how to pass data to the disconnect event:
socket.on('disconnect', function(){...})
it is being called automaticly when user disconnected.
I ned to have something like
socket.on('disconnect', function(user_name){
console.log('bye '+user_name);
})
but if that is possible (is it?) then how can I pass this parameter in the client side (my case, angular)?
my complete socket io server.js code is below.
io.on('connection', function(socket){
io.emit('chat_message', "welcome");
socket.on('room', function(room) {
socket.join(room);
});
socket.on('chat_message', function(data){
socket.broadcast.to(data.room).emit('chat_message',data.msg);
});
socket.on('info_message', function(data){
socket.broadcast.to(data.room).emit('info_message',data.msg);
});
socket.on('disconnect', function(){
console.log('bye '+socket.id);
io.emit('chat message', "Bye");
});
});
You can't pass data to the disconnect event. You can however attach your own properties to the socket object at some earlier point or you can keep your own map of sockets with additional information.
You just need to make sure that the server knows the user name for each socket (I can't tell from your question if the user name is a client-side or server-side piece of data). Then, you can just attach it to the socket object as a property. After doing that, when you then get the disconnect event, you can just look at that property on the socket that is disconnecting.
So, wherever the username info comes from, you set that property on the socket object at the time the server knows what it as and then you can do this for the disconnect:
socket.on('disconnect', function(){
console.log('bye ' + socket.user_name);
});
Or, if the user name is in a cookie, you can fetch that cookie value at any time by parsing socket.handshake.headers.cookie.

Cannot emit socket message from client

So, I'm setting up an express app, with all the usual goodies like passport, mongoose, connect-flash etc, and I'm using socket.io to listen for and emit messages.
Currently, I'm just emitting messages to everyone (will be setting up rooms later on) and everything (but this) is working great. When an end user visits any page, all currently connected users receive a message "Hi everyone!", and the user who just connected obviously sends them self the message too. All as expected so far...
The issue:
I have a page that has a button on it...
<button id="register" type="button" class="btn btn-warning">Register</button>
When clicked, this should emit a message saying 'I want to register!' (currently to everyone but that doesn't matter yet). In response, the server should listen for this and respond by emitting a message back saying 'Hmmm, will think about it!'.
'registering' is never heard at the server, and so cannot emit the reply of 'registration-response'.
Can anyone see what I'm doing wrong?
I've seen this SocketIO, can't send emit data from client and a couple others that are similar but I am already doing what they have suggested :/
NB: The app is running on http://localhost:3000/ and the io using http://localhost:8678/events. If you need any further info just let me know
Client-side JS/jQuery (app.js)
var app = app || {};
app = (function($){
$(function () {
/////////////////////////////////////////////////////
// Connect to io and setup listeners
/////////////////////////////////////////////////////
var socket = io.connect('http://localhost:8678/events');
socket.on('connected', function (data) {
console.log(data); // Always see this in the console
});
socket.on('registration-response', function (data) {
console.log(data); // NOT seen in console
});
/////////////////////////////////////////////////////
// Setup click events
/////////////////////////////////////////////////////
$('#register').on('click', function(){
console.log('click'); // Always see this, so no binding issue
socket.emit('registering', 'I want to register!');
});
});
})(jQuery);
Server-side JS
var app = require('express');
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server); //pass a http.Server instance
server.listen(8678); //listen on port 8678
////////////////////////////////////////
// Register event listeners
////////////////////////////////////////
var events = io.of('/events');
events.on('connection', function(socket){ // This is heard and callback fires
events.emit('connected', 'Hi everyone!'); // This gets sent fine
});
events.on('registering', function(data){
events.emit('registration-response', 'Hmmm, will think about it!');
});
Your socket on the server isn't set up to listen for the event.
You need to do it like this
events.on('connection', function(socket){ // This is heard and callback fires
events.emit('connected', 'Hi everyone!'); // This gets sent fine
socket.on('registering', function(data){
events.emit('registration-response', 'Hmmm, will think about it!');
});
});
The socket now knows what to do when it receives the 'registering' event and will send the response to the '/events' namespace.

How to emit an event in response to an event using socket.io?

I am new to socket.io, and trying to get it to work. I don't know what I am doing wrong here, as it seems super straightforward - yet it is not working. I suppose I am missing something obvious. Hopefully someone else can see what that is.
I am setting up socket.io to work with a node/express server. Here is a simplified version of the test I am trying to do.
Server:
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
/* socket.io test */
io.on('connection', function(socket){
socket.on('helloServer', function(clientMessage){
console.log("Server got 'helloServer' event");
socket.emit('helloClient', { message : "Hi there. We got your message: " + clientMessage.message});
});
});
The client has a function callServer that is called when a user clicks a button in the UI:
var socket = io.connect('http://localhost');
function callServer() {
socket.emit('helloServer', { message : "Hello server!" });
}
socket.on('helloClient', function (serverMessage) {
console.log(serverMessage.message);
});
When I run this code, and click the button that calls callServer, the server does get the event, helloServer, because I see that the console logs the message as expected, but the client never receives a helloClient event. It is as if the socket.emit call within the socket.on response function never gets called.
What am I doing wrong?
It appears to be ok. But, just in case, check this answer with all ways of sending data to clients and try use "io.emit" (to send to all clients). Or try sending a string instead of a json object.
I have tried this example here and it is working, just copied and pasted.

using Socket.io with iOS via the socket.io Swift client

I've been trying to do basic communication between an app and my server but no matter what I do I can't seem to get it to work.
Below is my js code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected');
io.emit("hello");
socket.on('disconnect', function() {
console.log('a user disconnected');
});
socket.on('response', function(message){
console.log(message);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
This should in theory be alerted when a user connects, output a message saying the user has connected and then emit an event "hello"
below the on disconnect part I am trying to communicate with the server from my iOS app. I emit a event called "response" with a string called "I got your response".
I get the "a user connected" message in the console but the message I send from the iOS app never gets printed in the console.
This the code in my app.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let socket = SocketIOClient(socketURL: "192.168.0.3:3000")
socket.on("hello") {data, ack in
socket.emit("response", "I got your response")
}
socket.connect()
}
As you can see my server side code emits the event "hello". This should trigger the socket.on("hello") and make the app emit the event "response" which makes the server print out the string sent with it.
None of this is happening apart from the message that gets printed in the console when a user connects.
An help would be greatly appreciated.
the Github repo for the framework is below
https://github.com/socketio/socket.io-client-swift
Declare and initiate your socket variable in the top of the class. As previous comments said, I think the variable is lost in the scope otherwise.
class HostSocketHandler {
let socket = SocketIOClient(socketURL: urlString)
init(){
socket.connect();
}
}

Categories