2010-02-04 10 views
0

Essentiellement, j'ai un serveur Java Socket de base comme vous pouvez le voir ci-dessous. Il permet à plusieurs utilisateurs de se connecter et quand ils lui envoient un message, il le renvoie. Cependant, je me demandais comment je pouvais le modifier, donc si un utilisateur envoie un message, plutôt que de le renvoyer, il l'envoie à tout le monde connecté? Donc, un serveur de base de discussion. Toute aide serait grandement appréciée :)Comment envoyer des messages à plusieurs utilisateurs?

import java.awt.Color; 
import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 

import java.io.*; 
import java.net.*; 

class ClientWorker implements Runnable { 
    private Socket client; 
    private JTextArea textArea; 

    ClientWorker(Socket client, JTextArea textArea) { 
    this.client = client; 
    this.textArea = textArea; 
    } 

    public void run(){ 
    String line; 
    BufferedReader in = null; 
    PrintWriter out = null; 
    try{ 
     in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     out = new PrintWriter(client.getOutputStream(), true); 
    } catch (IOException e) { 
     System.out.println("in or out failed"); 
     System.exit(-1); 
    } 

    while(true){ 
     try{ 
     line = in.readLine(); 
//Send data back to client 
     out.println(line); 
     textArea.append(line); 
     } catch (IOException e) { 
     System.out.println("Read failed"); 
     System.exit(-1); 
     } 
    } 
    } 
} 

class SocketThrdServer extends JFrame{ 

    JLabel label = new JLabel("Text received over socket:"); 
    JPanel panel; 
    JTextArea textArea = new JTextArea(); 
    ServerSocket server = null; 

    SocketThrdServer(){ //Begin Constructor 
    panel = new JPanel(); 
    panel.setLayout(new BorderLayout()); 
    panel.setBackground(Color.white); 
    getContentPane().add(panel); 
    panel.add("North", label); 
    panel.add("Center", textArea); 
    } //End Constructor 

    public void listenSocket(){ 
    try{ 
     server = new ServerSocket(4444); 
    } catch (IOException e) { 
     System.out.println("Could not listen on port 4444"); 
     System.exit(-1); 
    } 
    while(true){ 
     ClientWorker w; 
     try{ 
     w = new ClientWorker(server.accept(), textArea); 
     Thread t = new Thread(w); 
     t.start(); 
     } catch (IOException e) { 
     System.out.println("Accept failed: 4444"); 
     System.exit(-1); 
     } 
    } 
    } 

    protected void finalize(){ 
//Objects created in run method are finalized when 
//program terminates and thread exits 
    try{ 
     server.close(); 
    } catch (IOException e) { 
     System.out.println("Could not close socket"); 
     System.exit(-1); 
    } 
    } 

    public static void main(String[] args){ 
     SocketThrdServer frame = new SocketThrdServer(); 
    frame.setTitle("Server Program"); 
     WindowListener l = new WindowAdapter() { 
       public void windowClosing(WindowEvent e) { 
         System.exit(0); 
       } 
     }; 
     frame.addWindowListener(l); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.listenSocket(); 
    } 
} 

Répondre

0

Vous pouvez ajouter une petite modification en fournissant un support pour contenir tous les clients. Peut être une implémentation de List. Ensuite, vous pouvez écrire une méthode de diffusion et l'appeler au lieu de out.println(). Dans cette méthode, vous feriez la même chose en passant.

En outre, vous devriez regarder dans Observer Pattern pour implémenter ceci efficacement, plus vous obtiendrez une bonne compréhension d'un modèle de conception aussi. Un autre modèle qui serait utile ici est Mediator Pattern.

+0

Désolé si cela semble impoli mais comment j'irais faire cela? Je suis plutôt nouveau à Java et je construis un serveur à utiliser avec un autre projet, c'est le dernier morceau et je veux vraiment le finir :) – Ozzie

+0

Sans connaître votre conception globale, je ne pourrais pas pour te suggérer quelque chose d'exact. Alors, jetez un oeil ici http://www.codeproject.com/KB/IP/c_sharp_remoting.aspx. C'est un exemple d'application de chat basé sur Observer Pattern utilisant .NET. Je vais certainement vous donner un bon indice. –

+0

Ok, merci! Je regarderai!. Thats le programme dans son intégralité ha ha – Ozzie

0

Chaque fois que vous créez un nouveau ClientWorker dans listenSocket, conservez une référence au client dans une liste à laquelle tous les employés du client ont accès (qu'ils soient globaux ou, de préférence, passés lors de leur création). Lorsqu'un client reçoit un message, il peut parcourir la liste et renvoyer le message à chaque travailleur. Vous devrez faire attention en ajoutant/supprimant/itérant cette liste, car vous aurez beaucoup de threads qui pourraient tous essayer d'y accéder en même temps. Par ailleurs, pour plus d'exactitude, votre accès aux composants Swing (tels que textArea.append dans ClientWorker) doit être effectué à partir de l'EDT plutôt qu'à partir du thread du client. Voir les javadocs pour SwingUtilities.invokeLater.

Questions connexes