Am using nanomsg library with
int sock = nn_socket (AF_SP, NN_PAIR);
assert (nn_bind (sock, url) >= 0);
Now I want to know how to differentiate each connection in server if client connects.
In Regular Linux TCP Socket, we will get new socket fd on every connection accept,
am expecting some thing like that in nanomsg.
In below link am trying to use - Pair (Two Way Radio)
http://tim.dysinger.net/posts/2013-09-16-getting-started-with-nanomsg.html
I don't think you can by default.
Messages come in, and whenever a message comes in, you process it. There's no additional data on which client connected, or where the message came from.
Thus, my suggestion would be to let every client identify itself by a UUID at the start of every message, or wrap the messages in a JSON like format of which one key is used by the client to identify itself.
Related
Everytime a mobile user that is connected to my node.js, socket.io server leaves their browser (maybe checks instagram or something) the socket disconnects due to "transport close".
When they return I want them to reconnect using their old socket so they can receive buffered packets and have access to their old data stored in said socket.
What actually happens is that they reconnect and a new socket is created when the "connection" event is emitted in the server. The old socket is deleted too, unless I store it somewhere.
Are there any simple ways (config or something) to just reuse an old socket when a reconnection happens?
This post helped me a bit: reuse socket id on reconnect, socket.io, node.js. However it doesn't show me how to reuse the actual old socket.
Unfortunately after such event "transport close", by design the socket is destroyed.
So at this point you should look to other alternatives.
My suggestion is to introduce a new data structure which will store the messages in a list.
My proposal involves:
A map where the key is the user id and value is a list which contains all user messages.
You can store an offset to the structure which holds the list which marks the messages sent before the connection problem
On reconnect you lookup the map with the userid and retrieve the user messages
I am learning node and socket io. I have been watching tutorials, at first it is good, but then, they start to mix up using socket.on(), socket.emit() and io.on(), io.emit(). It seems very confusing. Can anyone clear my concept that where to use io and where to use socket in nodejs?
Logically think of io as the top level socket.io engine manager. If you want to do something at the top level that either creates some sort of resource like a socket or a new namespace object or sends a message to all existing connections in a namespace, then you use io.
Once you create a resource like a socket, you then use that object itself to operate on it.
On the server, you use io when you want to listen for new connections or when you want to broadcast to all connections. There are a few other things you can also do with it.
In the client, you use io when you want to connect to a server.
You use socket when you want to communicate with one particular connection as that connection is represented by the socket object. So, each client connection has a socket object and you send or receive info to/from that client by using methods on the socket object.
So, const socket = io.connect(url) or as a shortcut const socket = io(url) will connect a client to a server and give you the client-side socket object.
io.on('connection, socket => { ... }) will listen for an incoming client connection on the server and give you the socket for that new connection.
socket.emit() sends a message to the other end of that particular socket (whether on client or server).
io.emit() on the server sends a messages to all current connected clients (technically all clients connected to the top level io namespace - there can be other namespaces).
I'm developing a simple website, where the client and server communicate over web sockets. I'm using nodejs and the socket.io library for the socket communication
Specifically, my server works as a middleware between an mqtt broker and my client. So on one hand, my server connects with the mqtt broker to consume messages and on the other hand delivers these messages to the connected clients over web sockets. I'm using the node mqtt library for the mqtt communication.
My codebase is fairly large, so to give you a feeling of how my code looks like, I will show this example, which should be straightforward to understand:
const io = require("socket.io")(port);
handleRequests(io) {
io.on("connection", (socket) => {
logger.info(`New client connected: ${socket.id}`);
this.clients[socket.id] = { // track clients and subscribed topics
topic: '',
};
this.numberOfUsers++;
io.sockets.emit("onUser", this.numberOfUsers);
this.handleChange(socket);
this.addToSubscribedClients(socket);
this.removeFromSubscribedClients(socket);
this.handleDisconnect(socket);
this.sendMqttMessageToClient(socket);
});
}
This is my "main" function, where as you can see, I'm initializing an io object and using it later by passing it to the handleRequests function. Each time a new client connects, I'm calling the callback function where I call the five other functions and passing the socket object as a parameter, which should be fine I guess. I'm passing the socket object as a parameter because I need it to later call socket.emit in order to send back message to a specific client, since the socket object is unique for each client.
This works great until more than ~ 30 clients are connected. I'm trying to debug this for 2 weeks now and can't figure out why this is happening. I'm testing this by opening multiple tabs in my browser. I start with one client and then increase the number of clients/tabs. At some points, I notice that some clients receive no values from the server but other clients still do, which is incorrect since all clients should receive the values in real time.
I noticed that the clients, which are not receiving values have other ids than the ones stored on the server. I tested this with a simple console.log() on both clients and server. How this is happening? I'm very positive that I'm sending the ids correctly since there are other clients, which still receive values from the server. My guess is that the server is somehow disconnecting some clients automatically, because if a client reconnects then a new id will be assigned to it automatically.
Does anyone have any idea why this is happening? and why it works fine with the first ~30 clients and starts to occur when many clients are connected? This issue is very hard to debug since the code works fine for a small number of clients and no errors are thrown when the bug occurs, so I'm hoping that someone had this before.
Edit
Now I just found that i can print a reason for socket disconnection. When I do that, ping timeout is printed, which I don't understand because when I have one single or few clients connected then this error does not happen.
I have two node.js applications running side by side on my server and I wan't to send server-side messages between them in a light weight manner using native node.js (v0.10.33) module net
I intend the first application to send messages to the second. I see the console log listening...,
In the first application:
var push='';
var net=require('net');
var server=net.createServer(function(p){
p.on('error',function(err){console.log(err);});
push=p;
setInterval(function(){push.write(JSON.stringify({'f':'ping','data':'stay alive'}));},1000);
});
server.listen(8008,function(){console.log('listening...')});
//a real message might be sent later in the application (this example would need a setTimeout)
push.write(JSON.stringify({'f':'msg','data':'Hello World'}));
In the second application I see the console log open
var net=require('net');
var pull=new net.Socket();
pull.connect(8008,'127.0.0.1',function(){console.log('open');
pull.on('data',function(_){
_=JSON.parse(_);
if(_.f==='ping'){console.log('!!!ping!!!');}
else{console.log(_.data);}
});
pull.on('error',function(err){console.log('pull: '+err);});
});
I do not see any other activity though (no pings, and later after the open event, no hello world) and no errors.
If I inspect with console.dir(pull) I don't see events for accepting data ie: ondata or onmessage
What is wrong?
Unfortunately, I must point out that this messaging scheme is fundamentally broken. You're using TCP, which provides a stream of bytes, not messages.
Despite the fact that TCP sends its data over IP packets, TCP is not a packet protocol. A TCP socket is simply a stream of data. Thus, it is incorrect to view the data event as a logical message. In other words, one socket.write on one end does not equate to a single data event on the other. A single data event might contain multiple messages, a single message, or only part of a message.
The good news is this is a problem already solved many times over. I'd recommend either:
Using a library meant for passing JSON messages over TCP.
Using something like redis as a pub-sub messaging solution (this option makes your app much easier to scale)
If you know that your two apps will always run on the same machine, you should use node's built-in IPC mechanism.
In ASIO, s it possible to create another socket that has the same source port as another socket?
My UDP server application is calling receive_from using port 3000. It passes the packet
off to a worker thread which will send the response (currently using a dynamic source port).
The socket in the other thread is created like this:
udp::socket sock2(io_service, udp::endpoint(udp::v4(), 0));
And responds to the original request using the sender_endpoint saved with the original packet.
What I'd like to be able to do is respond to the client using the same source port as the server is listening on. But I can't see how that can be done. I get an exception if I try that saying address in use. Is it possible to do what I'm asking? The reason I want that is if I use dynamic ports, it means the clients need to add special firewall rules in windows to allow the reply packets to be read. I've found that if the source port is the same in the reply, windows firewall will allow it to pass back in.
The exception tells you as it is: you can't create two live sockets with the same source port. I don't know ASIO, but you should be able to create the socket before spinning off the thread, keeping reference to the socket and the thread for later use, and once the data sending thread is idle, joining back to it and sending any other stuff.
EDIT: with a little bit of effort, you can also make a socket for which you don't have to wait until the entire data from one thread has been sent: have a worker thread owning the socket listen on a queue for chunks of data (ideally exactly the size of the payload you intend to send) and send arbitrary chunks of payload to this queue, from multiple threads.
You should be able to use the SO_REUSEADDR socket option to bind multiple sockets to the same address. But having said that, you don't want to do this because it's not specified which socket will receive incoming data on that port (you would have to check all sockets for incoming data)
The better option is just to use the same socket to send replies - this can safely be done from multiple threads without any additional synchronisation (as you are using UDP).
send reply to the same socket (that you received client's request on) instead of creating new one
but make sure you don't send to the same socket from both threads simultaneously