Sending Message Requests - javascript

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.

Related

Role-based chat system in Nodejs

I've implemented a chat feature using socket.io and nodejs. But now I want to implement a role based chat application. For example, if someone wants to communicate with someone who is in a higher position, first needs to send a request. I've implemented a chat request system(similar to friend request). But I dont know how to make it role-based.
Can accesscontrol package be helpful in this case?
I've added a role property into the user model. I wanted to create a middleware to check what role has the user and to whom it wants to send the message. if its allowed it can continue with the 'chat', but if its not allowed I want it to redirect it to the request endpoint. I wanted to know if this logic is ok. If not, what could I do better.
EDIT: This solution with the middleware it seems to work :). If you have any better idea please answer my question
I don't have enough information to know exactly your case but it doesn't sound like you need access control. Here's my suggestion for you:
you need to store a role for each user.
when someone sends a message for the first time, you check if they can do it, doing something similar to this:
const senderRole = 'normal', receiverRole = 'extreme'; // YOU NEED TO FETCH THESE FROM YOUR DB
const roles = ['normal', 'better', 'extreme', 'best'];
if (roles.indexOf(senderRole) < roles.indexOf(receiverRole)) {
// need to ask for request
}
when they need to ask for request you would open a chat with the receiver but set in your database a special setting on the chat model: (access=false)
when the receiver goes in the app, they have a special section for chats filtered with the option (access=false), when they approve the chat, you change the setting and enable the chat to go back into the main queue and display messages

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).

How to remove particular messages in rabbitmq before publishing new messages?

I have a subscriber which pushes data into queues. Now the messages looks this
{
"Content": {
"_id" ""5ceya67bbsbag3",
"dataset": {
"upper": {},
"lower": {}
}
}
Now a new message can be pushed with same content id but data will be different. So in that i want to delete the old message with same id or replaece the message those id is same & retain only latest message.
I have not found a direct solution for this in rabbitmq. Please guide me how we can do this ?
I have already gone through some posts.
Post 1
Post 2
What you are trying to achieve cannot be trivially solved with RabbitMQ (or rather the AMQP protocol).
RabbitMQ queues are simple FIFO stacks and don't offer any mean of access to the elements beyond publishing at their top and consuming from their bottom.
Therefore, the only way to "update" an already existing message without relying on an another service would be to fetch all the messages until you find the one you are interested in, discard it, and publish the new one with the other messages you fetched together with it.
Overall, the recommendation when using RabbitMQ in regards of message duplication is to make their consumption idempotent. In other words, the consumption of 2 messages deemed to be the same should lead to the same outcome.
One way to achieve idempotency is to rely on a secondary cache where you store the message identifiers and their validity. Once a consumer fetches a new message from RabbitMQ, it would check the cache to see if it's a valid message or not and act accordingly.
I think this is a slightly wrong way to use rabbitMQ.
only immutable (not intended to change) tasks should be put into queues which a worker shall consume.
An alternative way to implement your particular task is
just push immutable data into queue { "content" : { "_id" : "5ceya67bbsbag3"} .. }
store mutable data in db (mongo) or in-mem db (something like redis is suggested here).
whenever update needed, update in db
let your worker fetch required data using your "_id" ref from the db
I am not sure if removing a message is a good idea. If your requirement is to update the data as it comes so that always latest data is maintained for same Id.
Other thing is as messages are getting consumed always the last message data will get updated. So I don't see a issue here in Rabbit MQ.

how to connect to sql database with js

I have form that to registering some site. I want to check when user is writing username code will check that have or not in database
You must use AJAX for this. The SQL database you speak of is on the host, not on the computer that is running the JavaScript.
When the user completes the registration page, you'll use AJAX to send the request to the host. The host might reply with an error response: "user already exists." It(!) is querying the database, which it(!) has access to, to determine this.
And ... if I may say ... "the Internet is positively stuffed with examples already!" Check out https://w3schools.com for some of the very-best free tutorials out there. Good luck!

check if a socket assigned a name is open

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

Categories

Resources