I am developing a Web-app with Angular (client-side) and Node (server-side). I'd like to integrate some social features, including a chat. So a user can discover near users and send them a message.
I want to know the best way to implement this. I have an idea, but it seems to me very raw, and I am afraid that it could overload the server.
my idea is to send each minute from the client, a request to the
server about new messages
the server looks for new messages among
all the conversations of that user, checking the last-message's
time for each conversation
the server sends back the conversations
with new messages
if the client receives conversations with new messages, a
notification appears, so the user can open the chat.
once the chat is opened, the request to the server for
new messages is sent each 3 seconds (instead of 1 minute)
Example of conversations of a user, stored in MongoDB
{'conversations':
[
{'to':{'user-id':'101010', 'name':'Michela', 'location':'Alba Adriatica',
'img':'http://graph.facebook.com...jpg'
},
'last-msg':12345, //epoch
'msgs':[
{'from-me':'ciao come stai?', 'date':''},
{'from-you':'bene grazie, tu?', 'date':''},
{'from-me':'eh insomma..mi so rott lu cazz', 'date':''},
{'from-you':'dai poi vai alle Hawaii', 'date':''}
]
},
...
]
}
You realy should learn about websockets and how they can provide 'push and pull' of information.
the approach your suggesting called 'long polling'. And yes, if the time between is not very long, the server will be under heavy load if the number of clients increases.
Using websockets you can let the server communicatie only with the clients that actually need the information.
Do a google search for "node.js chat application tutorial". It is not that difficult.
Related
I am looking for a solution to my problem. I have Node.js server serving my web application where user can log in. I want to handle a situation where one user A performs specific action and user B associated with this action gets real life notification. Is there a module that would help me or there is some other solution?
What you are describing is "server push" where the server proactively notifies a user on their site of some activity or event. In the web browser world these days, there are basically two underlying technology options:
webSocket (or some use socket.io, a more feature rich library built on top of webSocket)
server sent events (SSE).
For webSocket or socket.io, the basic idea is that the web page connects back to the server with a webSocket or socket.io connection. That connection stays live (unlike a typical http connection that would connect, send a request, receive a response, then close the connection). So, with that live connection, the server is free to send the client (which is the web page in a user's browser), notifications at any time. The Javascript in the web page then listens for incoming data on the connection and, based on what data it receives, then uses Javascript to update the currently displayed web page to show something to the user.
For server sent events, you open an event source on the client-side and that also creates a lasting connection to the server, but this connection is one-way only (the server can send events to the client) and it's completely built on HTTP. This is a newer technology than webSocket, but is more limited in purpose.
In both of these cases, the server has to keep track of which connection belongs to which user so when something interesting happens on the server, it can know which connection to notify of the event.
Another solution occasionally used is client-side polling. In this case, the web page just regularly sends an ajax call to the server asking if there are any new events. Anything new yet? Anything new yet? Anything new yet? While this is conceptually a bit simpler, it's typically far less efficient unless the polling intervals are spaced far apart, say 10 or 15 minutes which limits the timeliness of any notifications. This is because most polling requests (particularly when done rapidly) return no data and are just wasted cycles on your server.
If you want to notify userB, when both of you are simultaneously online during the action, then use websockets to pass message to a two-way channel to notify userB.
If you want to notify them whenever, regardless of online status, use a message queue.
I have a REST API server powered by express+mongodb. There are a couple of endpoints with different resources. One of them is chat API. I already have several basic endpoints like:
POST http://api.example.com/v1/chat - to create chat
POST http://api.example.com/v1/chat/:id/message - to send message to existing chat
GET http://api.example.com/v1/chat/:id/messages - to get messages in the the specified chat
But I need to provide a way for API consumers to efficiently get new messages in real-time without reloading the page.
For now as you see it's possible just to poll GET endpoint from client but it seems not performant. For example client can have UI which will show new messages count in header (some kind of notifications).
I was thinking about websockets. Is it possible for example to provide endpoint like /chat/:id/subscribe which will proxy sockets' server and connect to it on client?
Is there some good examples of such API design where I can get inspiration from or maybe you can give me piece of advice? Thanks!
socket.io is the package you are looking for.
The namespace section in it's documentation is a good solution because namespaces can be authorization protected. It represents a pool of connected sockets.
Here is how I would do it :
Create a document for the chat between the two users with this route :
POST http://api.example.com/v1/chat
Create a namespace with socket.io when a user sends a message to another connected user and store it into your user's document in your database. This route would create a namespace and/or emit the message :
POST http://api.example.com/v1/chat/:id/message
In the client, you have to use socket.io again to listen to the messages in the namespace.
UPDATE FOR SCALABILITY :
Here is a good stackoverflow answered question about implementing a scalable chat server : Strategy to implement a scalable chat server
As you can see in this post, mongodb might not be the best solution to store your messages.
I'm attempting to create an application which will work as a chat app. I'm currently contemplating the best way to do this and I'm thinking of going with a server sent event package such as the following. Every conversation would have an id, and the message would be emitted under the id. For instance
stream.emit(1512, "Hello") would send the message and
stream.on(1512, function(message){console.log(message)}) would print the message. Only the chat members would have the chatId.
I was initially thinking of using websockets but I thought that not every user should be receiving data, as chats were private and I didn't want to configure authentication within websockets.
Back to server sent events:
I have a few questions on the topic.
Are they efficient and, if not, what would be a more efficient solution
Is the method of sending chat through a randomized, hashed, id (such as 309ECC489C12D6EB4CC40F50C902F2B4D) secure?
Would you recommend a different method for sending chat? This is to be implemented as a mobile application where individual users can chat privately with oneanother so, again, security is pretty important.
Thanks.
I recommend the client-call package (disclaimer: I wrote it). It provides a very simple method to run a client-side method from the server code.
Besides this, you can always just put the chat messages to a db collection and remove them after some time.
I'm very new to node.js and sokcet.io that's why I need to ask you about the plan I have to see if it makes sense or is plain stupid. I need ongoing server/client communication for two reasons: sending real-time notifications to the user when they have one, and two, for chat between users.
Here is my plan for managing notifications:
PHP script finds out user X has a new notification.
Using Elephant.io send a message to server with user X's id as the data.
On the server side, upon receiving the message, if user X is connected emit him a message telling they have a notification.
user X's brower, Upon recieving the message, uses AJAX to poll the database and receive the text for the notification.
For chat, this is my plan (messages should be save on DB):
When user X submits a chat message to user Y, use ajax to send the text to a PHP script and save it on DB. On success, use elephant.io to send a message to user Y telling them that they have a new chat message.
User Y's browser, after receiving the server message, uses AJAX to poll a php script to receive the new text.
Do you think these plans are superior to short polling using AJAX? I appreciate any comments to improve them.
Finally,I'm curious to know how reliable these technologies (node.js, socket.io, elephant.io) are. Do they work well when the server becomes busy? How do they handle exceptions and errors ,etc.
I am new to server-side development. I'm trying to learn by doing so I'm building an application with express on the server, mongodb as my database and angularjs with twitter bootstrap on the client-side.
I dont know if this is the most practical way but when thinking about how to implement messaging between users I thought of a mongodb model called Conversation with an id and an array of the ids of every user in the conversation and another array of strings that correspond to messages. And then add this model to my REST API.
But lets say all/some of the users in the conversation are online, why not benefit from socket.io. So how can i switch from this to real time chat? Does the interaction with mongodb occure exactly as explained and socket.io just notifies every online user that an interaction has occured? If yes, how? Or is it something else?
socket.io can send real time events to connected sockets, you can use a database for storing messages that are failed to deliver and for offline users.
also, you might want to use something like Redis for this as it has channels with subscribe and publish capabilities.