websockets api中的session.getBasicRemote()。sendText()和session.getAsyncRemote()。sendText()有什么区别

时间:2018-08-01 06:45:59

标签: java

我是Java websockets api的初学者。

websockets api中的session.getBasicRemote()。sendText()和session.getAsyncRemote()。sendText()有什么区别

session.getBasicRemote().sendText("Hello");

session.getAsyncRemote().sendText("Hello");

2 个答案:

答案 0 :(得分:0)

使用getBasicRemote()可以同步发送您的消息。

通过getAsyncRemote(),您的消息将异步发送。

答案 1 :(得分:0)

这取决于实现,我们来看看undertow。

getBasicRemote() 最终调用 WebSockets.sendBlockingInternal(...),等待缓冲区被刷新:

private static void sendBlockingInternal(final PooledByteBuffer pooledData, WebSocketFrameType type, final WebSocketChannel wsChannel) throws IOException {
    boolean closePooledData = true;
    try {
        StreamSinkFrameChannel channel = wsChannel.send(type);
        // TODO chunk data into some MTU-like thing to control packet size
        closePooledData = false; // channel.send takes ownership of pooledData so it no longer needs to be closed
        if(!channel.send(pooledData)) {
            throw WebSocketMessages.MESSAGES.unableToSendOnNewChannel();
        }
        channel.shutdownWrites();
        while (!channel.flush()) {
            channel.awaitWritable();
        }
        if (type == WebSocketFrameType.CLOSE && wsChannel.isCloseFrameReceived()) {
            IoUtils.safeClose(wsChannel);
        }
    } finally {
        if (closePooledData) {
            pooledData.close();
        }
    }
}

getAsyncRemote() 调用异步刷新的 WebSockets.sendInternal(...),并注册完成后调用的 Future(callback)。

private static <T> void sendInternal(final PooledByteBuffer pooledData, WebSocketFrameType type, final WebSocketChannel wsChannel, final WebSocketCallback<T> callback, T context, long timeoutmillis) {
    boolean closePooledData = true;
    try {
        StreamSinkFrameChannel channel = wsChannel.send(type);
        // TODO chunk data into some MTU-like thing to control packet size
        closePooledData = false; // channel.send takes ownership of pooledData so it no longer needs to be closed
        if(!channel.send(pooledData)) {
            throw WebSocketMessages.MESSAGES.unableToSendOnNewChannel();
        }
        flushChannelAsync(wsChannel, callback, channel, context, timeoutmillis);
    } catch (IOException e) {
        if (callback != null) {
            callback.onError(wsChannel, context, e);
        } else {
            IoUtils.safeClose(wsChannel);
        }
    } finally {
        if ( closePooledData ) {
            pooledData.close();
        }
    }
}

所以不同的是,同步版本必须等待通道可写,并在通道写入后返回。