Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I need to design the similar stuff like whats app or any messenger like module.
High level flow
Client > Load Balancer > Web servers(assume 10 clustered server for now) > Rest based controller > Service > DAO > DB
Challenge :-
say Friend 1 and Friend 2 are online . Friend 1 has established HTTP web connection to web server 1 and Friend 2 has established HTTP web connection to web server 2.
Friend 1 send the message to Friend 2.
Now as soon as message comes to web server 1, i need to convey the message to web server 2 so that message can be pushed back to friend 2 through already established web connection
I have couple of related questions here :-
I can use distributed queues to propagate the message from one server to another. As soon as message comes to one server , it will push it to distributed queue(distribute
queue because of load balancing and high availability) with message content, fromUserId, toUserId. My question how the right server (in this case web server 2) will be notified ?
because if i use JMS queue , only one server will be notified through listener. If i use topic all servers will be notified . In this case all servers can reject the message except the one server where fromUserId resides. Is there a better way where queue just notifies the right server based on some meta data ?
Also if destinationUserId is offline, i need to put back the message on queue. Not sure how it can be achieved ? I believe we need to use some other queue implementation(probably java based in-memory queue)
instead of JMS queue/topic ? Server code will only remove the message from custom queue once it gets acknowledgement from client.
If any client is offline at the time message is sent, in that case whe he coming online,he will send the pull request . Server will make the request to distributed queue
, distributed queue will pull the message from right physical queue. My question ia should distributed queue will keep the destinationUserId and message as value in metadata ?
DB vs Queue :- With this approach i believe there is no need to store the message in DB which can be costly(time complexity) than queue(in-memory queue) in highly real time application like messenger. We just need to store user/group details in db.
Update :- I found related link at quora where last point i.e. What protocol is used in Whatsapp app ?... by Kah Seng Tay also confirms the simialr approach using queue , but still my above questions on queue are yet to be answered.
Related
I am implementing websockets for collaborative editing. For that I am using Spring 5 websockets.
The simplest example would be, two web clients are connected via websockets to my server. User 1 does some action which creates an event and sends this event info to my server. Now this event has to be sent to User 2 so that they can do appropriate UI changes.
I have two questions here:
Since there will be multiple instances running of this server, User 1 might connect to Server 1 and User 2 might connect to server 2. In this case how would the changes done by User 1 go to User 2 ?
Also, I was following this tutorial. This tutorial is implementing websockets without any message broker some tutorials are additionally using a message broker (amqp mostly). What is the point of a message broker in this case ? Is it only used because there might be too many messages and the server would be processing them one by one ?
Just wanted to add: We cannot get away with a peer to peer connection on the client side as the server needs to store the data for future.
By default spring 5 uses in memory simple stomp broker for all connections
If you want to scale horizontally you need a message broker like RabbitMQ etc.
Lets imagine the situation user1 and user2 is connected to server1 and user3 is connected to server2 . When user1 sends a message to user3 it would not be aware of user3 because server1 does not know about user3.
If we have a broker this issue will be solved.
So scalability is needed to handle the load and in production you always will have more than 1 instance for high availability and fault tolerance.
After googling how message is sent/received in chat messenger like whatsapp, i came across they use queues based messaging system. I am just trying
to figure out what can be high level design of this feature
HLD per mine understanding :-
Say Friend 1 and Friend 2 are online . Friend 1 has established HTTP web connection to web server 1 and Friend 2 has established HTTP web connection to web server 2. Friend 1 send the message to Friend 2.
Now as soon as message comes to web server 1, i need to convey the message to web server 2 so that message can be pushed back to friend 2 through already established web connection.
I believe distributed custom java queues can be used here to propagate the message from one server to another. As soon as message comes to one server , it will push it to distributed queue(distribute queue because of load balancing and high availability) with message content, fromUserId, toUserId. There will be listener on queue which will see destination userId of just poppedIn message and find on which webserver destination userId is active . If user is active pop out the message and push it to client otherwise store it in db so that it can be pulled
once once gets online. To see which user is active on which server, there we can maintain the treemap with userId as key and value as serverName for efficient look up
Probably actual design must be more complex/scalable than above brief . Would like to know if this is the right direction for scalable chat messenger?
Also i believe we need to have multiple distributed queues instead of one for such a scalable application. But if we have multiple distributed queues how system will ensure the FIFO message delivery across distributed queues ?
Would like to know if this is the right direction for scalable chat
messenger?
Designing this application using message queues has the following benefits:
Decoupling of client-server and reduce of failure blast: Queues can gracefully handle traffic peaks, by just having a temporarily increased queue size, which will be back to normal as long as traffic normal again (or any transient failures have been fixed)
In a messaging application, clients (mobiles) can be offline for long periods. As a result, a synchronous design would not work, since the clients might not be accessible for message delivery. However, with an asynchronous design as with message queues, the responsibility of message delivery is on the client side. As a result, the client can poll for new messages as soon as it gets online.
So, yes this design could be quite scalable in terms of performance and usability. The only thing to have in mind is that this design would require a separate queue for each user, so the number of queues would scale linearly with the number of the application's users (which could be a significant financial & scalability issue).
But if we have multiple distributed queues how system will ensure the
FIFO message delivery across distributed queues ?
Many queues, either open-source (rabbitMQ, activeMQ) or commercial (AWS SQS), support FIFO ordering. However, the FIFO guarantee inside the queue is not enough, since the messages sent by a single client could be delivered to the queue in different order due to asynchronicity issues in the network (unless you are using a single, not-distributed queue and TCP which guarantees ordered delivery).
However, you could implement FIFO ordering on the client side. Following this approach, the messages would include a timestamp, which would be used by each client to sort the messages when receiving them. The only side-effect of that is that a client could see a message, without having seen all the previous messages first. However, when previous messages arive, they will be shown in the correct order in the client's UI, so eventually the user would see all the messages and in the correct order.
Would like to know if this is the right direction for scalable chat messenger?
I would probably prefer a slightly different approach. Your ideas are correct, but I would like to add up a bit more to the same. I happened to create such a chat messenger a few years ago, and it was supposed to be quite similar to watsapp. I am sure that when you googled, you would have come across XMPP Extensible messaging and presence protocol. we were using openfire as the server that maintains connections . The concept that you explained where
Say Friend 1 and Friend 2 are online . Friend 1 has established HTTP web connection to web server 1 and Friend 2 has established HTTP web connection to web server 2. Friend 1 send the message to Friend 2.
is called federation, and openfire can be run in a federated mode. After reading through your comments, i came across the one queue per user point. I am sure that you already know that this approach is not scalable as its very resource intensive. A good approach would be use an Actor framework such as akka. Each actor is like a light weight thread in java and each actor has an inbox. so messaging is taken care of in this case.
So your scenario transforms to Friend 1 opens a connection to openfire xmpp server and initializes a Friend 1 Actor.When he types a message, it is transferred to the Friend 1 actor's in-box ( Each actor in akka has an in memory inbox). This is communicated to the xmpp server. The server has a database of its own, and since it is federated with other xmpp servers, it will try to find if friend 2 is online. The xmpp server will keep the message in its db until the friend 2 comes online. Once friend 2 establishes a connection to any of the xmpp server a friend 2 actor is created and its presence is propagated to all other servers and the xmpp server 1 will notify Friend 2's actor. Friend 2's actor inbox will now get the message
Optional: There is also a option of delivery receipt. Once Friend2 reads the message, a delivery receipt can be sent to friend 1 to indicate the status of the message i.e read, unread, delivered, not delivered etc.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
So I previously asked a question if you can send a client that's on a ServerSocket to a different Server. But now, I'm asking how are the players for minecraft sent from server to server using Bungeecord and/or Lilypad. I know that LilyPad uses proxies and that stuff, but how are the players, when connected to the Bungeecord/Lilypad server, sent to a hub/spawn and/or to other servers, for example a survival server and a creative server. You can find servers like this on servers that have networks. I know that Treasure wars uses lilypad, if that helps.
You answered your own question. Both Bungeecord and LilyPad are proxy server networks.
Though a server cannot redirect the client to another server without permission, the server can connect to another server (meaning the first server is a proxy) and send back that server's messages to the client. As the first server is, in essence, also a client to the second server, the first server can switch connections at any desired point.
In other words, the Minecraft client does not switch connections at any point. The IP of the server to which the Minecraft client is connected never changes, and it is that of the proxy. However, what does change is the server to which the proxy is connected. If the client sends some message to the proxy stating that it wishes to go to the hub, the proxy then disconnects from whatever server it is currently connected to, connects to the hub, and sends back to the Minecraft client whatever messages the hub responds with.
This is my understanding based on a quick search.
However, if the Minecraft client was modded as well, it would be possible to have a similar network without the need for a proxy like so:
Client interacts with the server in such a way (maybe the player walks into a portal) as to trigger some server-switching action.
The server recognizes this interaction and, as both it and the client are modded, knows how to respond. The response is simply the sending of a message to the client, saying, "Switch to a different server. Here is the IP: (Insert IP here)"
The client receives the message from the server and, by its own will, disconnects from the current server and reconnects to the new one.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have a Java TCP/IP client and server program that exchanges data based on requests from the clients. I now need to implement multiple instances of this server, with each one holding a subset of the data, with the client still only connecting to the master server. What is the best way to go about this, preferably without multithreading?
(I agree in that multithreading would be an improvement for high availability and performance, though it's not strictly necessary.)
If you want an scheme like this:
{ ---> slave server 1
client ---> master server { ---> slave server 2
{ ---> slave server 3
... then, you'll have to add to the master server a client API, because it will have a double role: As a server, to receive requests from the client/s, and as a client to send requests to the slave servers.
If you have already implemented a client/server communication protocol, then it would be useful to reuse that same protocol for communicate master/slave servers.
You must also address the binding matter: How does the master know how many and which slaves there are?
If they run in the same host, the master itself could start the slaves.
If they run in different hosts, you'll have to provide this addressing information to the master: Either by static configuration in the master, either by making the slaves send the master an address message as soon as each one of them is started (this implies a complication in the master/slave protocol).
And there's still the availability problem: What if one of the slaves shuts down?
If the network data is wisely distributed between the slaves, in order to produce a high amount of redundant data, the problem gets solved just making the master poll the slaves one by one until he gets all the needed data (of corse, this will still serve for just one or two slaves being off simultaneously; if many of the slaves shut down, there can be no gurantee to maintain the data available. Redundancy has a limit).
If there is no redundancy at all, the master will have to detect this situation, and react properly:
If they run in the same host, the master can re-start any of the servers dynamiclly.
If they run in different hosts, the master can do no other thing than report the problem to the client through an apporpiate error message.
Data synchronization can be an issue if they share writable data. In this case, the master will have to broadcast the same writing to each affected slave.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I was planning to create a chat messaging application wherein two or more clients can communicate but I am a little confused.
Does java can have a client to client communication using sockets?
Does the socket communication always needs a server?
Is it possible that one client will stand a server of the communication?
Do you have any tutorials for a client to client communication?
If the communication needs a server, how a can a client A see Client B's messages?
Client to client communication does not makes any sense because once a system start receiving message it is termed as server, so in communication there should be a server and client to communicate else the situation will be like two people talking and none of them listening.
Client A can act as a server and client both and so the client B,
in doing so both can communicate in two way ie send and receive information.
Yes, java can work with sockets.
For example, an "official" tutorial from Oracle: http://docs.oracle.com/javase/tutorial/networking/sockets/
But working with sockets directly requires a lot of code for encoding/decoding message from/to a binary form, separating data stream to logical "packets", handling threads and message queues, etc. Fortunately, there are network libraries which make this process much more easier. I would recommend Netty: http://netty.io/
About client/server relationships. If we are talking about TCP/IP, then yes. One side (server) always listens for connection, and the other side (client) opens a connection to the server.
If you are using UDP, however, from network point of view, all participants are equal. They just send and receive UDP packets.
Back to your chat application: the most simple solution - all clients connect to the dedicated server. Every chat message contains client id. When the server receives the message, it sends it to the client with the specified id. Thus, every client can transfer message to every other client. The server works as a "dispatcher".
If you need simple approach you can try https://httprelay.io service. What you need is just http client and no external libraries.