Working with Socket.io sending and receiving objects - javascript

Here is my app.js file
io.on('connection', function(socket){
socket.on('ujwal', function (data) {
socket.emit('news', function(){
console.log('testing');
});
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
On ujwal event i am emitting another event to the client
here is my index.html i have included socket lib too
var socket = io('http://localhost:3000');
$('#test').click(function(){
var as = "object";
socket.emit('ujwal',as);
});
socket.on('news', function (a) {
alert('receiving msgs');
});
Now i am opening two windows whenever a user click a test id they are getting but who are not clicking they are not receiving the object in front end why? why code means whenever u get name event ujwal please fire news A and B are connected to server A click the test ujwal is fired and checking by server and again send back news now all the user connected should see the alert ?
This what i know so please make it work so that all user can get alert.

When you use socket.emit(), you're emitting directly to that socket, not all sockets. To emit to all sockets, emit from io
io.on('connection', function(socket){
socket.on('ujwal', function (data) {
//socket.emit('news', function(){
io.emit('news', 'some message');
});
socket.on('disconnect', function(){
console.log('user disconnected');
});

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.

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();
}
}

How can I get the socket ID from an event in Socket.io?

I want to know which client sent an event when it arrives on the server. For example:
var socket = require(socket.io')(port);
socket.on("ask question", function(data){
var socketid = // ?
//respond to sender
socket.sockets.connected[socketid].emit("Here's the answer");
});
How can I get the socket ID of the event sender?
Your server-side logic is a bit off. The client connects and that's where the client socket is revealed and that's where you listen to events from a particular client. Usually, it would look like this:
var io = require("socket.io")(port);
io.on('connection', function (socket) {
socket.on('ask question', function (data) {
// the client socket that sent this message is in the
// socket variable here from the parent scope
socket.emit("Here's the answer");
});
});
This is shown in the socket.io docs here.

socket.io/node.js detecting if server is down

Is there something that I can do on the client side to detect that the socket.io websocket is not available? Something along the lines of:
server starts as per usual
clients connect
messages are sent back and forth between server and client(s)
server shuts down (no longer available)
warn the connected clients that the server is not available
I tried to add the 'error' and 'connect_failed' options on the client side but without any luck, those didn't trigger at all. Any ideas from anyone how I can achieve this?
The disconnect event is what you want to listen on.
var socket = io.connect();
socket.on('connect', function () {
alert('Socket is connected.');
});
socket.on('disconnect', function () {
alert('Socket is disconnected.');
});
If you want to be able to detect that the client was not able to connect to the server, then try using connect_error. This works for me with socket.io-1.3.5.js. I found this in https://stackoverflow.com/a/28893421/2262092.
Here's my code snippet:
var socket = io.connect('http://<ip>:<port>', {
reconnection: false
});
socket.on('connect_error', function() {
console.log('Failed to connect to server');
});
hit this bug during my development and noticed my event calls were doubling up every time i reset the server, as my sockets reconnected. Turns out the solution that worked for me, which is not duping connections is this
var socket = io.connect();
socket.on('connect', function () {
console.log('User connected!');
});
socket.on('message', function(message) {
console.log(message);
});
( Found this at https://github.com/socketio/socket.io/issues/430 by KasperTidemann )
Turns out, it was becuase I put the 'message' listener inside the 'connect' function. Seating it outside of the listener, solves this problem.
Cheers to Kasper Tidemann, whereever you are.
Moving on!!
connect_error didn't work for me (using Apache ProxyPass and returns a 503).
If you need to detect an initial failed connection, you can do this.
var socket;
try {
socket = io();
}
catch(e) {
window.location = "nodeServerDown.php";
}
Redirects the user to a custom error page when the server is down.
If you need to handle a disconnect after you've connected once.
You do this:
socket.on('disconnect', function() {
//whatever your disconnect logic is
});

Categories