Java-网络-最佳实践-混合同步/异步命令



我正在用Java开发一个小型客户端-服务器程序。

客户端和服务器通过一个tcp连接进行连接。通信的大多数部分是异步的(可以在任何时候发生),但有些部分我希望是同步的(比如发送命令的ACK)。

我使用一个线程从套接字的InputStream中读取命令,并引发一个onCommand()事件。命令本身由命令设计模式进行。

什么是最佳实践方法(Java),可以在不错过其他可能同时出现的命令的情况下等待ACK?

con.sendPacket(new Packet("ABC"));
// wait for ABC_ACK

编辑1

把它想象成一个FTP连接,但数据和控制命令都在同一个连接上。我想在后台运行数据流时捕捉对控制命令的响应。

编辑2

所有内容都以块为单位发送,以便在同一TCP连接(多路复用)上进行多次(不同)传输

Block:
1 byte - block's type
2 byte - block's payload length
n byte - block's paylod

原则上,您需要一个被阻止线程的注册表(或者更好的是,它们正在等待的锁),用一些将由远程端发送的标识符进行键控。

对于异步操作,您只需发送消息并继续。

对于同步操作,在发送消息后,您的发送线程(或启动此操作的线程)会创建一个锁对象,将其与某个密钥一起添加到注册表中,然后等待锁,直到收到通知。

当读取线程接收到一些答案时,它会在注册表中查找锁对象,将答案添加到其中,并调用notify()。然后读取下一个输入。

这里的难点是正确的同步,以避免死锁和丢失通知(因为它在我们将自己添加到注册表之前就回来了)。

当我为Fencing小程序实现远程方法调用协议时,我做了类似的事情。原则上,RMI以相同的方式工作,只是没有异步消息。

@Paulo的解决方案是我以前使用过的。然而,可能有一个更简单的解决方案。

假设您没有后台线程读取连接中的结果。相反,您可以使用当前线程来读取任何结果。

// Asynchronous call
conn.sendMessage("Async-request");
// server sends no reply.
// Synchronous call.
conn.sendMessage("Sync-request");
String reply = conn.readMessage();

最新更新