Avatar billede 123maka Nybegynder
20. april 2010 - 23:55 Der er 3 kommentarer

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
Avatar billede simonvalter Praktikant
21. april 2010 - 00:17 #1
Der er altid java.nio som er asynkron eller f.eks dette der simplificerer brugen af det lidt http://code.google.com/p/naga/

kunne forestille mig det var hensigtsmæssigt ikke at benytte tråde når man tænker på hvor mange brugere en irc server tit har.
Avatar billede 123maka Nybegynder
21. april 2010 - 11:10 #2
Naga ser okay ud, det vil jeg se lidt på.

Tråde tror jeg ikke er et problem, regner med MAX 200-300 brugere samtidig. Jeg synes dog at Naga opfører sig væsentligt anderledes end de alm. sockets.
Avatar billede 123maka Nybegynder
23. april 2010 - 16:27 #3
Nogen der kender noget til xSocket?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester