Java nio上下文中的请求-响应同步/匹配

Java nio上下文中的请求-响应同步/匹配,java,netty,guava,communication,grizzly,Java,Netty,Guava,Communication,Grizzly,我有一个服务器客户端应用程序(JavaEE和Android),通过WebSocket进行通信。通信工作正常,协议本身也可以将对象作为json发送,json将被正确包装、序列化、发送、反序列化、取消包装和重建。这两个应用程序正在使用另一个库项目,其中包含所有可能的请求和响应类 现在来看看我的问题: 库还应该实现一种非阻塞通信的策略,但实现透明的请求-响应。可能我不是第一个遇到这个问题的人,所以我认为可能会有一些很好的实现:) 我想要什么: // server should sleep 5000ms

我有一个服务器客户端应用程序(JavaEE和Android),通过WebSocket进行通信。通信工作正常,协议本身也可以将对象作为json发送,json将被正确包装、序列化、发送、反序列化、取消包装和重建。这两个应用程序正在使用另一个库项目,其中包含所有可能的请求和响应类

现在来看看我的问题: 库还应该实现一种非阻塞通信的策略,但实现透明的请求-响应。可能我不是第一个遇到这个问题的人,所以我认为可能会有一些很好的实现:)

我想要什么:

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