I have a application in which I am using socket programming , having this(image) scenario.
Where number of clients will try to connect Broadcast server.
Now here I am managing load through LVS(Load balancer). so as a example shown in image, suppose 200 clients will wish to login for broadcast they will be distributed as 100 users on server 1 and another 100 users on server 2.clients will get connected to servers using TCP connection.
Now I am maintaining user information on server side in arraylist which will be stored in heap memory,Now the problem is if client wish to broadcast to all logged in users, but that particular client is logged in server 1. and so client will not be able to broadcast another 100 users from server 2. Because both ther servers are unaware about each others state.
please suggest me to solve this scenario by whatever means you want.
Have the two servers log in to each other and arrange for broadcasts to be forwarded to the other server and then on to that server's clients.
Related
I would like to know the architecture of real time chat for millions of users like whatsapp.
I implemented a chat but I need to use more servers to handle more clients
I read another question, but I still have doubts about.
Tell me if what I say is correct:
Clients connect to load balancer that decide to give connection to one of the whatsapp servers.
Example ClientA connect to Server1,
ClientB connect to Server2,
-If ClientA wants to communicate with ClientB, sends a message to the Server1 ,now, this how do you know in which server is ClientB ? Maintaining the scalability to millions of users )
How to implement a chat to handle millions of users?
The key is the database (or any other persistence system) where all the input from the clients gets stored. Usually in these scales, a key-value NoSql Database is suitable, like Apache Cassandra, Amazon Dynamo, or Google Datastore.
These databases are optimal for fast insert and fetch by PK only.
All the servers need to be stateless, so Client A connects to Server A and sends a text message and destination client Id. This gets stored in the DB. Then, client B connets to Server B which goes to the database and retrieves the text.
We are working on a Android project with the below requirements.
The application should be able to send data to all the devices which are running our application which exists in the WiFi LAN.
Some payloads are expected to be of size >= 5MB.
The data shouldn't be lost and if lost the client should know the failure.
All the devices should be able to communicate with all other. There will be no message targeted to a specific device instead all the messages should be reached all the devices in the N/W.
No internet hence no remote server.
Study we have done:-
UDP Broadcasting - UDP doesn't guarantee the message delivery but this is a prime requirement in our case. Hence not an option.
TCP - TCP guarantees the message delivery but requires the receiver IP address to be known before hand and in our case we need to send the message to all the devices inside the LAN. Hence not a straight option.
Solutions we are looking into:-
A Hybrid approach - Name one of the devices in the N/W as Server. Post all the messages to a local Server. The Server keeps a open socket to all the devices(which have our application) & when there is a message from a device then it routes the message to all the devices. The disadvantages of this approach are,
Server having multiple sockets open each per device. But in our case we are expecting devices <=5 in LAN.
Server discovery using continuous UDP broadcast.
We want to have all the data in all the devices. So if we newly introduce any device into the LAN then that device needs to get all the data from the server.
So my question, have you any time worked on these kind of hybrid approaches? Or can you suggest any other approaches?
Your hybrid approach is the way to go.
Cleanly split your problem into parts and solve them independently:
Discovery: Devices need to be able to discover the server, if there is any.
Select server: Decide which of your devices assumes the server role.
Server implementation: The server distributes all data to all devices and sends notifications as necessary. Push or pull with notifications does not matter.
Client implementation: Clients only talk to the server. The device which contains the server should also contain a normal client, potentially passing data to the server directly, but using the same abstract protocol.
You could use mDNS (aka Bonjour or zeroconf) for the discovery, but I would not even recommend that. It often createsmore problems than it solves, and it does not solve your 'I need one server' problem. I would suggest you handcraft a simple UDP broadcast protocol for the discovery, which already tells you who the server is, if there is any.
Select server: One approach is to use network meta data which you have anyway, for example 'use the device with the highest IP address'. This often works better than fancy arbitration algorithms. Once you established a server new devices would use this, rather than switching the server role.
Use UDP broadcast for the discovery, with manual heuristic repeats. No fancy logic, just make your protocol resilient against repeated packets and repeat your packets. (Your WLAN router may repeat your packets without your knowledge anyway.)
You may want to use two TCP connections per client, potentially to two different server ports, but that does not matter much: One control connection (always very responsive, no big amounts of data, just a few hundred bytes per message) and one data connection (for the bulk of the data, your > 5 MB chunks). This is so that everything stays responsive.
I need to have a UDP server which allow me to receive/send informations from/to clients which dynamically will open a socket with a free port (so it will be differente from device and device). The client will send and receive in the same port, so the server must be able to communicate with it.
how could I set the server to stay open in every port? if I had 250 thousand users how could I handle them without tails problem and preventing the port to be occupied from another client?
I thought about open every port with different sockets in a different thread, but I don't know if this is a correct way.
A UDP Server can listen and be open on only one port. All clients can send data to that port. The server will have to handle each data and respond if needed to the peer who sent its data. This should happen even if more than one client wish to send data to server. In UDP context one client will not hog the server port.(Unless the application is badly written).
First of all sorry for the long winded title but i was unable to think of a suitable title, considering my question.
Now to the problem. I am creating a peer to peer chat application, which has the ability to send and receive files while also being able to chat to individual contacts.
I understand i can capture the ip of the client connecting to the server and store this, then when that user starts a chat session to another person. I can use that stored ip to create a connection between the two clients using the ServerSocket.
BUT i do not wish to pass one users ip to another users computer for security reasons so, what i am asking basically is there a way to connect two clients together without passing each client each others ip.
so for e.g
(all sockets have read / write buffers )
Client 1-- logs in --> Server ( a session ID 1 is created between the client 1 and server )
Client 2-- logs in --> Server ( a session ID 2 is created between the client 2 and server )
Client 1 --- Starts chat with client 2 ---> Server ( server connects session 1 and session 2)
Client 1 can then chat and send files to client two without passing it the ip.
I am sorry if this is a unclear question or even stupid but i could not think of a way to even Google this question.
You would need to run the connection through a server. You could use the server to buffer the connection between the two clients and connect their communications in a way that would seem nearly seamless.
For example you could create a thread that, as long as both clients are connected, waits for input from client 1 and immediately pipes it to client 2. And the same would be necessary vice-versa. Is this the kind of solution you were looking for?
I have a spreadsheet application in Java, and one of the features it provides (which I developed) is sheet sharing. Basically, anyone can be a client or a server because the app has both server and client code. The user who is the server creates the share, specifies the IP, and then the share is created and active (best case scenario) with the server listening for clients on its IP and selected port.
At the moment, the client needs to enter the IP and port of the server that's listening in order to connect. The server then creates a new socket for that client and communicates with in on a separate thread, while the server continues listening on another (traditional TCP behavior). This is all working fine.
What I need to develop is auto-discovery, e.g. a client does not need to type in an IP or port, they simply select 'Join a share...' from the menu and then it starts looking for servers. When one is found, it should send its list of active shares on that IP. The user then selects which share to join from the list, and is connected.
However, I have doubts on how to tackle this issue. Should I use broadcast to poll servers, like DHCP does? Or is there an easier way?
What I'd like to implement is:
Client -> polls local network -> finds a server -> server sends active share list to client -> client selects share to join -> connected!
Technically, what you're looking for is active servers that are running your spreadsheet application.
One possibility would be for your server code to send out an "alive" message to the network every so often (say every 15 seconds). Your client code would listen for these "alive" messages, and produce a meaningful list of spreadsheet servers.
Another possibility would to to use the same database engine that you're using to store the spreadsheets to store the IP and port of the connected server code. The client code would just read the database table to get the connections.