【问题标题】:How to flush buffer when ConcurrentWebSocketSessionDecorator bufferSizeLimit exceeded?超过 ConcurrentWebSocketSessionDecorator bufferSizeLimit 时如何刷新缓冲区?
【发布时间】:2018-08-07 09:31:28
【问题描述】:

我在项目中使用Spring Websocket,发现ConcurrentWebSocketSessionDecorator在超出bufferSizeLimit时停止了,但是没有办法恢复。

我是这样用的:

try {
    if (concurrentWebSocketSessionDecorator.isOpen()) {
        concurrentWebSocketSessionDecorator.sendMessage(message);
    }
} catch (SessionLimitExceededException se) {
    logger.warn("sendMessage exceed limit: ", se);
    // TODO flush buffer
} catch (IOException ie) {
    logger.error("sendMessage failed: ", ie);
}

我看了concurrentWebSocketSessionDecorator的代码,方法checkSessionLimits设置limitExceeded=true并抛出SessionLimitExceededException超出缓冲区大小,但我找不到任何设置 limitExceeded=false 的方法。如何刷新缓冲区并重置 limitExceeded?

public void sendMessage(WebSocketMessage<?> message) throws IOException {
    if (shouldNotSend()) {
        return;
    }

    this.buffer.add(message);
    this.bufferSize.addAndGet(message.getPayloadLength());

    do {
        if (!tryFlushMessageBuffer()) {
            if (logger.isTraceEnabled()) {
                String text = String.format("Another send already in progress: " +
                        "session id '%s':, \"in-progress\" send time %d (ms), buffer size %d bytes",
                        getId(), getTimeSinceSendStarted(), getBufferSize());
                logger.trace(text);
            }
            checkSessionLimits();
            break;
        }
    }
    while (!this.buffer.isEmpty() && !shouldNotSend());
}

【问题讨论】:

    标签: java spring websocket concurrency spring-websocket


    【解决方案1】:

    它在已经运行的tryFlushMessageBuffer()中自行刷新:

    private boolean tryFlushMessageBuffer() throws IOException {
        if (this.flushLock.tryLock()) {
            try {
                while (true) {
                    WebSocketMessage<?> message = this.buffer.poll();
                    if (message == null || shouldNotSend()) {
                        break;
                    }
                    this.bufferSize.addAndGet(message.getPayloadLength() * -1);
                    this.sendStartTime = System.currentTimeMillis();
                    getDelegate().sendMessage(message);
                    this.sendStartTime = 0;
                }
            }
            finally {
                this.sendStartTime = 0;
                this.flushLock.unlock();
            }
            return true;
        }
        return false;
    }
    

    我明白你关于limitExceeded 标志的观点:我们只是不去那个tryFlushMessageBuffer(),因为我们已经在shouldNotSend() 之后存在。那是因为你是对的,limitExceeded 永远不会被重置。

    听起来真的像一个错误。请就此事提出 JIRA:https://jira.spring.io/projects/SPR

    【讨论】:

    猜你喜欢
    • 2015-08-10
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2021-09-03
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多