Lille socket-server, mulighed for asynkron IO?
Hej Eksperter!Jeg er ved at bygge en simpel IRC-lignende server. Jeg har valgt en trådbaseret approach, som starter en ny tråd til hver klient.
Jeg har også introduceret rum i systemet, så en bruger kan kun tale til det rum som han befinder sig i. Det har ført mig til følgende design:
public class Person extends Thread
{
private int id;
private String nick;
Room room = null;
Socket socket = null;
ObjectOutputStream out;
ObjectInputStream in;
@Override
public void run()
{
this.init();
this.chatLoop();
}
private void chatLoop()
{
String cmd = "";
try {
while (!cmd.equals("client shutdown"))
{
// Everything from the CLIENT -> SERVER is being handled here!
cmd = (String) in.readObject();
this.room.broadcastToRoom(this, cmd);
}
out.close();
in.close();
socket.close();
}
catch(SocketException se)
{
this.signoff();
}
catch (Exception e)
{
System.out.println(this.nick);
e.printStackTrace();
}
}
public void recieveCmd(String cmd)
{
try {
this.out.writeObject(cmd);
this.out.flush();
} catch (IOException ex) {
// Fejl i overførsel?
}
}
}
Det som der sker når brugerne skriver til serveren, så må de kun skrive til dem som de er i rum med (Jeg skal have lavet noget locking på de objekter som indeholder rum, og brugere). Men kommandoen bliver sendt til deres room-objekt med metoden this.room.broadcastToRoom. BroadcastToRoom ser således ud:
public void broadcastToRoom(Person from, String cmd)
{
this.writeToRoom(from.getID() + ";" + cmd);
}
private void writeToRoom(String cmd)
{
Collection c = this.roomPersons.values();
Iterator itr = c.iterator();
while (itr.hasNext()) {
IPerson p = (IPerson)itr.next();
p.recieveCmd(cmd);
}
}
Den invoker altså personernes recieveCmd. Dette er lidt et problem:
- Langsomme forbindelser er langsomme om at sende til, og de blokerer for beskeden for de andre brugere i rummet.
- Hvad nu hvis et person-objekt modtager 2 beskeder meget hurtigt? Kan man lave en kø af en art?
Nogen ideer til en nem og simpel løsning? Evt. et pseudo kode eksempel