After successfully implementing user authentication, the next step toward enabling real-time messaging is retrieving a list of online contacts. Without this list, users have no one to commnuicate with.
Upon successful login, the server spawns a dedicated thread to manage ongoing communication with that client, allowing it to handle additional login requests concurrently.
if (u.getOperation().equals("login")) {
int userId = u.getAccount();
boolean isAuthenticated = new UserDao().login(userId, u.getPassword());
if (isAuthenticated) {
System.out.println(MyData.getDate() + "'" + userId + "' connected!");
m.setType(YQMessageType.SUCCESS);
oos.writeObject(m);
ServerConClientThread clientHandler = new ServerConClientThread(s);
ManageServerConClient.addClientThread(userId, clientHandler);
clientHandler.start();
} else {
m.setType(YQMessageType.FAIL);
oos.writeObject(m);
}
}
This dedicated thread listens for incoming messages from the client and processes them based on they type:
public class ServerConClientThread extends Thread {
private Socket socket;
public ServerConClientThread(Socket socket) {
this.socket = socket;
}
public void run() {
while (true) {
try {
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
YQMessage msg = (YQMessage) input.readObject();
if (msg.getType().equals(YQMessageType.COM_MES)) {
ServerConClientThread recipientHandler =
ManageServerConClient.getClientThread(msg.getReceiver());
ObjectOutputStream output =
new ObjectOutputStream(recipientHandler.socket.getOutputStream());
output.writeObject(msg);
}
else if (msg.getType().equals(YQMessageType.GET_ONLINE_FRIENDS)) {
// Temporary implementation: returns all registered users as friends
String userList = new UserDao().getUser();
ServerConClientThread senderHandler =
ManageServerConClient.getClientThread(msg.getSender());
ObjectOutputStream output =
new ObjectOutputStream(senderHandler.socket.getOutputStream());
YQMessage response = new YQMessage();
response.setType(YQMessageType.RET_ONLINE_FRIENDS);
response.setContent(userList);
output.writeObject(response);
}
} catch (Exception e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException ignored) {}
break;
}
}
}
}
On the client side, after logging in successfully, a background thread maintains the connection to the server:
if (ms.getType().equals(YQMessageType.SUCCESS)) {
ClientConServerThread connectionThread = new ClientConServerThread(context, s);
connectionThread.start();
ManageClientConServer.addClientConServerThread(user.getAccount(), connectionThread);
b = true;
} else if (ms.getType().equals(YQMessageType.FAIL)) {
b = false;
}
The client then immediately requests the on line friends list:
ObjectOutputStream out = new ObjectOutputStream(
ManageClientConServer.getClientConServerThread(user.getAccount())
.getSocket().getOutputStream()
);
YQMessage request = new YQMessage();
request.setType(YQMessageType.GET_ONLINE_FRIENDS);
request.setSender(user.getAccount());
out.writeObject(request);
Once the server responds with the list (currently all users due to simplified logic), the client populates a ListView using a standard adapter—implementation details of which are omitted here.