关于ConcurrentWebSocketSessionDecorator的一个问题

最近想起了看一下websocket,想起之前一个项目里遇到过的问题。使用的是spring里的spring-boot-starter-websocket依赖。使用websocketsession.sendMessage()方法,因为这个方法并没有做线程安全处理,所以多线程对同一个发消息会出现java.lang.IllegalStateException。

最初就是加synchronized,但是并发高时阻塞严重。ConcurrentWebSocketSessionDecorator,这是 Spring WebSocket 提供的一个装饰器类,用于增强底层的 WebSocketSession 的线程安全性。它通过并发安全的方式包装原始的 WebSocketSession 对象,确保在多线程环境下安全地访问和修改会话属性,以及进行消息发送操作。

但是看ConcurrentWebSocketSessionDecorator代码发现一个问题:

public void sendMessage(WebSocketMessage<?> message) throws IOException {
        if (!this.shouldNotSend()) {
            this.buffer.add(message);
            this.bufferSize.addAndGet(message.getPayloadLength());
            if (this.preSendCallback != null) {
                this.preSendCallback.accept(message);
            }

            do {
                if (!this.tryFlushMessageBuffer()) {//尝试发送失败后退出了循环
                    if (logger.isTraceEnabled()) {
                        logger.trace(String.format("Another send already in progress: session id '%s':, \"in-progress\" send time %d (ms), buffer size %d bytes", this.getId(), this.getTimeSinceSendStarted(), this.getBufferSize()));
                    }

                    this.checkSessionLimits();
                    break;
                }
            } while(!this.buffer.isEmpty() && !this.shouldNotSend());

        }
    }

private boolean tryFlushMessageBuffer() throws IOException {
        if (!this.flushLock.tryLock()) {//获取锁失败直接返回
            return false;
        } else {
            try {
                while(true) {
                    WebSocketMessage<?> message = (WebSocketMessage)this.buffer.poll();
                    if (message == null || this.shouldNotSend()) {
                        return true;
                    }

                    this.bufferSize.addAndGet(-message.getPayloadLength());
                    this.sendStartTime = System.currentTimeMillis();
                    this.getDelegate().sendMessage(message);
                    this.sendStartTime = 0L;
                }
            } finally {
                this.sendStartTime = 0L;
                this.flushLock.unlock();
            }
        }
    }

在获取锁失败,未能发送消息后退出了,除了检查一些限制checkSessionLimits后并没有做其他操作,虽然未能发送的消息保存在buffer队列中,下次可以再发。但是万一就是最后一条消息,不会再有下次发送,对某个客户端来说直到连接断开都不会再调用sendMessage()方法了,那放在buffer队列中的消息就一直没发出去。。。虽然自己可以做一些重调机制。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值