2011-04-25 41 views
0

寻找对以下问题的建议。确保客户端请求的正确响应

我正在使用单个TCP套接字来读写消息到服务器的应用程序(客户端)。

消息是几种预定义类型之一,它们在抵达时将被解析。

服务器可能随时广播消息。

客户端会向服务器发送消息,并期待响应。然而(这里是我的问题来了),我不能从套接字读取收到此消息,因为我不知道什么时候可以传递。大多数情况下,客户端响应消息将在客户端请求后立即传递。但是,偶尔会有另一个广播消息被首先发送。

套接字的读取通道由单个生产者线程排入阻塞队列。在一个单独的消费者线程中,任何消息都会出队并发送,以供进一步处理。为了获得预期的客户响应,我应该使用事件源/侦听器语言来让我的客户在其(如果)响应到达时得到通知吗?

感谢您的任何建议。

编辑:我认为我的问题不清楚,因为迄今为止的建议不处理手头的问题。最后,我确实使用了事件源/侦听器成语来处理这个问题。再次感谢errort,但我认为这是封闭的。主持人甚至可能想删除这个问题。

回答

0

这是使用Java的序列化机制的绝佳机会。你可以这样做(假设你捕获所有异常有关,这是为了简明扼要省略)

class ClientListeningThread { 

    ObjectInputStream in; 
    ObjectOutputStream out; 

    ClientListeningThread(Socket s) { 
     in = new ObjectInputStream(s.getInputStream()); 
     out = new ObjectOutputStream(s.getOututStream()); 
    } 

    public void run() { 
     while(true) { 
      ClientMessage message = (ClientMessage)in.readObject(); 
      engine.addMessage(this,message); // add to the message queue, signifiying which listening thread to give the response to 
     } 
    } 

    public void send(ServerMessage message) { 
     out.writeObject(message); 
    } 

} 

您的邮件甚至可以在它们回调

类LoginMessage {

public final String username; 
public final String password; 

public LoginMessage(String username, String password) { 
    this.username = username; 
    this.password = password; 
} 

public void callback(ClientListeningThread thread, ServerProcessor engine) { 
    ServerMessage response = engine.attemptLogin(username,password); 
    thread.send(response); 
} 

}

而在你的发动机

while(!requests.isEmpty()) { 
    ClientRequest request = requests.poll(); 
    ClientListeningThread = request.thread; 
    ClientMessage message = request.message; 
    request.callback(thread,this); 
} 
+1

看不到序列化在这里发挥作用。另请参阅我的编辑。不管怎么说,还是要谢谢你。 – 2011-04-30 18:06:02

0

您可以使用侦听器和缓存线程池来实现它。所以你可以创建一个处理消息的Runnable类。然后创建一个监听器类,它只是实例化一个套接字(或服务器套接字)并创建一个线程池。在监听器类中创建一个无限循环,用于监听传入请求并将socket.accept传递到可运行对象的构造函数中,以便它可以处理来自套接字的任何输入。

代码会是这个样子:

public class MessageHandler implements Runnable { 

    String msg = ""; 
    Socket socket = null; 
    BufferedReader in = null; 
    PrintWriter out = null; 

    public void MessageHandler(ServerSocket socket){ 
     this.socket = socket; 
    } 

    @Override 
    public void run(){ 
     //Message read from socket 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     System.out.println("Message: " + in.readLine()); 

     //Reply send back through same socket 
     out = new PrintWriter(socket.getOutputStream(), true); 
     out.println("MESSAGE RECEIVED. THANKS."); 
    } 
} 

你听类将是这个样子:

public class SocketListener { 

    ServerSocket socket = null; 
    ExecutorService threadExecutor = null; 
    Runnable runnable = null; 

    public static void main (String[] args){ 
     socket = new ServerSocket(8181); 

     /* Socket will always be listening, when a request arrives a thread will handle 
     * the incoming stream. 
     */ 
     while(true) { 
      threadExecutor = Executors.newCachedThreadPool(); 
      runnable = new MessageHandler(socket.accept); 
      threadExecutor.execute(runnable); 
     } 
    } 
} 

我不知道这是否代码编译,但你的服务器的实现可以看起来与此非常相似,并且可以扩展和强大。

您的客户可以是几乎相同的,虽然你会使用插槽不是的ServerSocket,也许不同的方式处理消息。

+0

请参阅我的编辑。不管怎么说,还是要谢谢你。 – 2011-04-30 18:06:46

相关问题