check if a socket assigned a name is open - javascript

I wan to to check if a specific socket is open. I am using socket.io. I assign the socket connection a name like
socket.username = username;
when the connection is made, but is there a way to check if that is open from another connection? Basically checking if a user is online
I hope this makes sense.
Thanks

Taking into account that network maybe slow, even if a given user is »online«/connected, it might easier to define »online« in terms of response time. So the easiest thing to do is to broadcast a »ping« event to a user and wait for its »pong« response. This way you not only check if the user is connected at all, because you can measure the response time as well and consider the user to be offline in case the response took too long.
Docs for a basic send/receive
update
So if I am getting this right, that might be the answer

Related

How to establish a communication between two users, if the id generated by the socketIO are auto generated?

Hello I hope you are very well, I would like to ask you a question that I have not been able to deduce the answer to.
In a course I was seeing that to send a message to a specific user with socketIO.js the to () method is used and the id as a parameter, but I have a doubt, that id is auto generated by socketIO as far as I understand, so I would like to know How can the frontend know that id? The example that I saw in the course does it from the console and sends it directly to the method with the id that it already knows, then that example is not so real, what I would like to know in itself How is it that it performs a one-to-one chat if the id is autogenerated by the socket? I don't know if I understand.
For example, to start a conversation with another user, you can click on a button, trigger an event that makes emit, send the id of the user who writes, the event that should trigger the backend with socket, but my question is how does it taste like who send the message? How do you know the id of who is being sent to when establishing communication between 2 users for the first time? Obviously this must be sent by frontent as a parameter but also how does the frontend give this id of who will it be sent to? I don't know if you can store a fixed socket id for a user in a DB or Can you use your DB id to use with sockets? more than everything is what I can not deduce how it would be done?
I do not know if I understood with the question, more than everything is that, I do not know how it obtains or assigns the id for the target from where the message is sent and if this can be fixed and stored in db or is there any method to this.
I thank you in advance for your response, and any resources that you share with me about it or if you recommend a course with, I would greatly appreciate it.
as an example I have this method
io.on('connection', (client) => {
client.on('privateMessage', (data)=>{
const person = user.getPersona(client.id) //get this
client.broadcast.to(data.para).emit('privateMessage', createMsj( person.name, data.messages));
});
}
But where does the front-end of the person to receive the message to pass it to the method?
The front-end will not know the socket.io id of any other clients. This is where your server needs to be involved.
Each of your users presumably has some username that is displayed in the client UI and this is the name that other clients would know them by.
So, your server needs to keep a mapping between username and socket.io clientID. So, a user can send a request to your server to connect to BobS. Your server then needs to be able to look up BobS, find out if that user is currently connected and, if they are, then what is their socket.id value. That way, your server can facilitate connecting the two users.
This mapping would not typically be kept in a permanent store (such as a database) because the socket.id is a transient value and is only good for the duration of that client's socket.io connection. As such, it is more typically just kept in some sort of Javascript data structure (such as a Map object).

Sending Message Requests

I am making a chat application using Socket.IO and Node.JS. I would like to implement message requests, such as the ones Facebook's Messenger has. I am not sure how to go about this problem.
If Mike wants to send a private message to Jake, Jake must first accept Mike's message request. Let's say Mike connects to the server using Socket.IO, and the server handles his request. Mike can then send sockets to the server, for example, a chat socket such as the one below:
socket.emit( 'chat', { // Emits the 'chat' socket to the server
name: 'Mike', // Sets the name of the sender
receiver: 'Jake', // Sets the name of the receiver
message: 'Hey Jake!' // Sets the message
} );
Now, obviously, this socket should be sent IF ANY ONLY IF Jake accepted the message request already. This is where the problem lies.
Message requests are stored in a database ( this is necessary for my application ).
I have a few ideas in mind on how to accomplish this:
Query the database each time a user sends a chat socket, to see if the receiver accepted the sender's request. Of course, this would mean that each time a chat is sent, I have a database query. This seems highly inefficient to me.
Query the database once somehow, and allow chat messages to go through without issuing a database query every time - although I am not sure how to accomplish this - hence this question.
I would love your input on this problem. Thanks!
The request you mentioned, is that request accepting should happen just once, like in facebook or it should be accepted for every message sent.
I hope it is just once, when the first message is sent. If this is the case then you can create a JSON file with an array containing Jake's friends(people accepted by Jake). Whenever someone tries to send a message to Jake, you just refer to the JSON files Jake's array to see if the sender is in the array list. If yes you can proceed with broadcasting message to Jake. If not in the array, send Jake a connection request from sender(Mike).
Since you are storing message requests in database, update the JSON file arrays when ever a new connection request is accepted by some one.
I hope this helps you. Comment below, if I am out of your scope anywhere.
There are multiple ways.
1) You can have caching done (as mentioned by #PM-77-1) which helps decrease number of database queries. Redis cache is really easy to use with Node.js. So whenever you are trying to check if Mike has Jake as a friend you can first check at cache level if Jake is in Mike's friend list. If Mike's friend list is not available you can fetch it from db once and store it in cache for future use.
2) You can also allow a user (Mike) to send around 100 to 200 short messages (just an example) and the messages are hidden for Jake until Jake accepts Mike's request. Having a limit on number of messages Mike can send without being a friend is a subjective question and it depends upon how famous application it is.

socket.io without using default namespace/room feature

I found it's easier to just setup own custom path for multiple endpoints like this
server side:
io.on('connection', function(client) {
var username = client.handshake.headers.users[0].username;
client.on(username+'_con1', function(data) {
io.emit(username+'_con1',data);
});
client.on(username+'_con2', function(data) {
io.emit(username+'_con2',data);
});
}
Is above approach correct? at least I'm able to make it work.
Depending on what you mean by correct. This will create multiple events for the client.
Its hard to say if this is the best/correct way without any context. But you should look into namespaces and rooms and decide for yourself! http://socket.io/docs/rooms-and-namespaces/
Creating unique message names for each client makes it seem like you plan on sending a message to all clients and only some clients will be listening for the message directed at them. This is not a very efficient way to do things.
Rooms in socket.io are designed such that you can have a common message name (no need for a unique message name for each client) and then send that message only to the clients that it is intended for. That's a lot more efficient scheme.
Now, of course, you could create the unique message name for each client and then only send it to the desired client, but why bother with the extra complication of the unique message name. You don't need it if you're only sending the message to the intended client.
So, you could certainly make your scheme work, but it does not seem like it's the simplest way to do things and, depending upon other details of your implementation, it may not be the most efficient way to do things either.
A namespace is more like connecting to a particular channel. The client decides what channel they want to connect to. The server then decides which namespace to send a given message to.
A room is a something a server subscribes a client to in order to make it easy to send a specific set of clients the same messages or in some cases to share incoming messages from one client with all the other clients in a room (like in chat).

Node js connecting two socket so that retrieving would be easier

Currently now i am using io.emit where i send the event to all the connected users and in client side i check whether the id of user i emit is equal to the id of client side then the condition runs i thinks its making my code messy and bit slow is there anything i can do like connecting then in one group so when retrieving them i would be easier for me.
//server side
var id = 1;
io.emit('check',id);
// on client side
socket.on('check',function(data){
var current_user_login = //getting current user login id by php
if(data == current_user_login) {
//run some code
}
});
If you want to put certain sockets in the same room, so that it's easy
to broadcast to all of them together. Try this:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.join('group');
socket.broadcast.to('group').emit('new member');
});
Hope this helps.
The better way to solve this problem is to create an association between the user you want to send the data to and that user's socket so you can .emit() only to that particular socket. This is much, much more efficient than sending to everyone especially when you have lots of connected sockets.
You would have to explain to us much more about how you know which socket or user you want to send to in order for us to help figure out how to do that association in your server.
socket.io has the concept of "rooms" which are groups of sockets that makes it easy for you to place a socket in a specific group and to then broadcast to a specific group of sockets.
Or, each socket has an id and each socket has access to the cookies that were present when the connection was first made, both of which can sometimes be used to identify which user you want to send to. But, you'd have to explain how you know which user you want to send to for us to help give you an idea how to code that into your server.

Private messaging through node.js

I'm making a multiplayer (2 player) browser game in JavaScript. Every move a player makes will be sent to a server and validated before being transmitted to the opponent. Since WebSockets isn't ready for prime time yet, I'm looking at long polling as a method of transmitting the data and node.js looks quite interesting! I've gone through some example code (chat examples, standard long polling examples and suchlike) but all the examples I've seen seem to broadcast everything to every client, something I'm hoping to avoid. For general server messages this is fine but I want two players to be able to square off in a lobby or so and go into "private messaging" mode.
So I'm wondering if there's a way to implement private messaging between two clients using nodejs as a validating bridge? Something like this:
ClientA->nodejs: REQUEST
nodejs: VALIDATE REQUEST
nodejs->ClientA: VALID
nodejs->ClientB: VALID REQUEST FROM ClientA
You need some way to keep track of which clients are in a lobby together. You can do this with a simple global array like so process.lobby[1] = Array(ClientASocket, ClientBSocket) or something similar (possibly with some additional data, like nicknames and such), where the ClientXSocket is the socket object of each client that connects.
Now you can hook the lobby id (1 in this case) onto each client's socket object. A sort of session variable (without the hassle of session ids) if you will.
// i just made a hashtable to put all the data in,
// so that we don't clutter up the socket object too much.
socket.sessionData['lobby'] = 1;
What this allows you to do also, is add an event hook in the socket object, so that when the client disconnects, the socket can remove itself from the lobby array immediately, and message the remaining clients that this client has disconnected.
// see link in paragraph above for removeByValue
socket.on('close', function(err) {
process.lobby[socket.sessionData['lobby']].removeByValue(socket);
// then notify lobby that this client has disconnected.
});
I've used socket in place of the net.Stream or request.connection or whatever the thing is.
Remember in HTTP if you don't have keep-alive connections, this will make the TCP connection close, and so of course make the client unable to remain within a lobby. If you're using a plain TCP connection without HTTP on top (say within a Flash application or WebSockets), then you should be able to keep it open without having to worry about keep-alive. There are other ways to solve this problem than what I've shown here, but I hope I got you started at least. The key is keeping a persistent object for each client.
Disclaimer: I'm not a Node.js expert (I haven't even gotten around to installing it yet) but I have been reading up on it and I'm very familiar with browser js, so I'm hoping this is helpful somehow.

Categories

Resources