2010-02-04 2 views
0

По существу у меня есть базовый сервер Java Socket, как вы можете видеть ниже. Он позволяет нескольким пользователям подключаться, и когда они отправляют ему сообщение, он возвращает его обратно. Однако мне было интересно, как я могу его редактировать, поэтому, если пользователь отправляет ему сообщение, а не просто отправляет его обратно, он отправляет его всем подключенным? Итак, базовый чат-сервер. Любая помощь была бы принята с благодарностью :)Как отправлять сообщения нескольким пользователям?

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(); 
    } 
} 

ответ

0

Вы можете добавить небольшую модификацию, предоставив держатель для хранения всех клиентов. Может быть реализацией списка. Затем вы можете написать широковещательный метод и вызвать его вместо out.println(). В этом методе вы, кстати, делаете подобное.

Кроме того, вы должны изучить Observer Pattern, чтобы эффективно реализовать это, плюс вы также получите хорошее представление о шаблоне дизайна. Другой пример, который будет полезен здесь, - Mediator Pattern.

+0

Извините, если это звучит грубо, но как я могу это сделать? Я довольно новичок в Java, и я строю сервер для использования с другим проектом, это последний его бит, и я действительно хочу его закончить :) – Ozzie

+0

Без знания вашего общего дизайна я бы не смог предложить вам что-нибудь точное. Итак, посмотрите здесь http://www.codeproject.com/KB/IP/c_sharp_remoting.aspx. Его пример приложения чата на основе шаблона Observer с использованием .NET. Определенно предоставит вам хороший намек. –

+0

Хорошо, спасибо! Я взгляну!. То, что программа в целом ха-ха – Ozzie

0

Каждый раз, когда вы создаете новый ClientWorker в listenSocket, держите ссылку на клиента в списке, к которому все рабочие клиенты имеют доступ (будь то глобальный или, желательно, - переданный в них при их создании). Когда клиент получает сообщение, он может перебирать список и отправлять сообщение каждому работнику. Вам нужно быть осторожным при добавлении/удалении/повторении через этот список, так как у вас будет много потоков, которые могли бы одновременно попробовать и получить к нему доступ.

Кроме того, для корректности ваш доступ к компонентам Swing (например, textArea.append в ClientWorker) должен выполняться из EDT, а не из потока клиента. См. Javadocs для SwingUtilities.invokeLater.

Смежные вопросы