Java nio上下文中的请求-响应同步/匹配
我有一个服务器客户端应用程序(JavaEE和Android),通过WebSocket进行通信。通信工作正常,协议本身也可以将对象作为json发送,json将被正确包装、序列化、发送、反序列化、取消包装和重建。这两个应用程序正在使用另一个库项目,其中包含所有可能的请求和响应类 现在来看看我的问题: 库还应该实现一种非阻塞通信的策略,但实现透明的请求-响应。可能我不是第一个遇到这个问题的人,所以我认为可能会有一些很好的实现:) 我想要什么:Java nio上下文中的请求-响应同步/匹配,java,netty,guava,communication,grizzly,Java,Netty,Guava,Communication,Grizzly,我有一个服务器客户端应用程序(JavaEE和Android),通过WebSocket进行通信。通信工作正常,协议本身也可以将对象作为json发送,json将被正确包装、序列化、发送、反序列化、取消包装和重建。这两个应用程序正在使用另一个库项目,其中包含所有可能的请求和响应类 现在来看看我的问题: 库还应该实现一种非阻塞通信的策略,但实现透明的请求-响应。可能我不是第一个遇到这个问题的人,所以我认为可能会有一些很好的实现:) 我想要什么: // server should sleep 5000ms
// server should sleep 5000ms and then return 3*3
Future<Integer> f1 = server.put(
new SleepAndReturnSquareRequest(5000, 3),
new FutureCallback<Integer>{
public void onSuccess(Integer square) {
runOnUiThread(new Runnable{
// Android Toast show square
});
}
// impl onFailure
}
);
Future<Date> f2 = server.put(
new TimeRequest(),
new FutureCallback<Date>{
public void onSuccess(Date date) {
// called before other onSuccess
}
// impl onFailure
}
);
// e.g. when the activity in android changes I'll cancel all futures. That means no more callbacks and (later) if possible client sends cancellations to the server for long requests.
对我来说,有很多东西需要测试,但我认为它会起作用。你可以尝试-但它不适用于WebSocket,尽管我认为GitHub上有一个项目支持它:)grizzly或netty中有什么东西可以为我工作吗?你需要一些东西在客户端生成transactionId,这就是你的问题吗?@Thorynque no.这是关于如何通过WebSocket实现请求和响应的同步。使用唯一的事务id是很明显的。阅读我上面的代码。我认为websocket协议处理这种匹配,将websocket对象(由incomming resquet创建)传递给工作线程。在JavaEE中,一个websocket对象表示到客户端的一个连接。但无论如何,上面没有处理请求/响应匹配的协议。它是双向的。我发送一个字符串并接收一个字符串。在返回两个响应后可能有两个请求,或者在第一个请求之后立即有一个响应,然后是另一个响应
public class Synchronizer<K, V> implements UniqueMessageListener<K, V> {
private final ConcurrentMap<K, FutureCallback<V>> callbackMap = new ConcurrentHashMap<>();
private final ListeningExecutorService executor;
private final UniqueMessageFactory<K, V> factory;
private final UniqueMessageSender<K, V> sender;
private UniqueMessageReceiver<K, V> receiver = null;
public Synchronizer(
ListeningExecutorService executor,
UniqueMessageFactory<K, V> factory,
UniqueMessageSender<K, V> sender
) {
this.executor = executor;
this.factory = factory;
this.sender = sender;
}
public void register(UniqueMessageReceiver<K, V> receiver) {
unregister();
this.receiver = receiver;
receiver.addListener(this);
}
public void unregister() {
if(receiver != null) {
receiver.removeListener(this);
receiver = null;
}
}
public Future<V> put(Message<V> message, final FutureCallback<V> callback) {
final UniqueMessage<K, V> uniqueMessage = factory.create(message);
final Future<Boolean> sendFuture = sender.send(uniqueMessage);
final ListenableFuture<Boolean> listenableSendFuture =
JdkFutureAdapters.listenInPoolThread(sendFuture, executor);
listenableSendFuture.addListener(
new Runnable() {
@Override
public void run() {
try {
if(listenableSendFuture.get() == true) {
callbackMap.put(
uniqueMessage.getId(),
callback
);
} else {
// maybe try it later again?
}
} catch(Exception e) {
// ...
}
}
},
executor
);
// implement cancel
return new SynchronizeFuture<>(
listenableSendFuture,
callback
);
}
@Override
public void onReceive(UniqueMessage<K, V> message) {
K id = message.getId();
FutureCallback<V> callback;
callback = callbackMap.remove(id);
if(callback != null) {
callback.onSuccess(message.getContent());
}
}
}