I have a project where I have to build a system where multiples server communicate between each other to respond to clients.
I can make the client communicate with the server but I'm having problems on making the servers start a connection between them.
In the code below you can see that I have a list with the ip's of all the server. For each ip the current server tries to connect with the other server. You can also see that the server wait's for connections, in these case, connections from the other servers.
@Override
public void run() {
// Trying to connect with server
for (String serverIp : servers) {
System.out.println("Trying to connect with " + serverIp);
try {
Socket clientSocket = new Socket(serverIp, this.port);
this.clientPool.submit(new ClientThread(clientSocket, this.streamHandler));
} catch (Exception e) {
System.out.println("Error");
}
System.out.println("Connected with " + serverIp);
}
// Receiving connections from other servers
// In these case we call client to the other server
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
this.clientPool.submit(new ClientThread(clientSocket, this.streamHandler));
}
// serverSocket.close();
} catch (IOException e) {
Configuration.printError("Error starting server", e);
}
}
The problem is that the server needs to try to connect with the other servers and wait for connections from the other servers. And after receiving a new connection it needs to stop trying to connect to the correspondent server or if the server have success trying to connect with the other server, it needs to stop receiving new connections from that server.
Any suggestions on how to implement this with sockets?
It seems like you try to do this in steps, first all servers try to connect to the others, but no server have started to accept connections yet. And after the clientSocket has connected to servers, you then start to accept connections. It sounds like this can lead to a deadlock.
You know that each server must accept connections from other servers. You also know that each server need to initiate connections to the other servers.
You must either accept connections and initiated connections in two different threads, or you should use an asynchronous/event driven model and manage an event loop.
Here you want to avoid a race. This is easiest to do if each server wait X time before trying to connect to the other servers. This X should be a random delay from startup. E.g. server A waits 5 seconds before connecting, server B waits 1 second, and server C waits 13 seconds before connecting. But server B and C will not initiated any connections since server A already have established connections to those servers.