使用java-websocket框架开发websocket客户端时遇到的两个问题

WebSocketClient objects are not reuseable
You cannot initialize a reconnect out of the websocket thread. Use reconnect in another thread to insure a successful cleanup.

今天主要解决如上这两个问题。
使用的java-websocket版本是1.5.1
参考的文章:
关于WebSocket的 WebSocketClient objects are not reuseable
使用WebSocket实现Android端即时通讯聊天功能

上面两篇文章把引发问题的原因描述的比较清楚了,但是还是可以做补充说明。
我报上面这两个错的原因是在onclose中调用了connect与reconnect。
先说解决方法,在onClose中不要使用connect与reconnect,在其他线程中使用connect与reconnect,也就是除了监听onClose事件的线程,任何代码块中调用都是可以正常连接或重连的。
个人的方案是通过重写send方法,在send前检查连接状态来判断是否需要重连。

@Override
	public void send(String text) {
		boolean open = isConnectOpen();
		if (open) {
			super.send(text);
		}
	}

	/**
	 * 在连接断开时尝试重连
	 *
	 * @return
	 */
	public boolean isConnectOpen() {
		int t = 0;
		if (null == this) {
			return false;
		}
		// 连接断开
		while (!this.isOpen()) {
			try {
				log.info("重连服务器...");
				if (this.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) {
					super.connectBlocking();
					return true;
				} else if (this.getReadyState().equals(ReadyState.CLOSING) || this.getReadyState().equals(ReadyState.CLOSED)) {
					super.reconnectBlocking();
					return true;
				}
			} catch (Exception e) {
				log.error("reconnect error ", e);
			} 
		}
		return true;
	}

现在分析具体代码

问题一: WebSocketClient objects are not reuseable

使用java-websocket框架开发websocket客户端时遇到的两个问题_第1张图片

如上图,抛出这个异常时,表示当前连接已经被初始化过了(调用过connect方法),connectReadThread已经被初始化过了。
而当websocketclient对象初始化时(下图),不建立连接,直到调用connect方法时,才为connectReadThread初始化。
使用java-websocket框架开发websocket客户端时遇到的两个问题_第2张图片

问题二:You cannot initialize a reconnect out of the websocket thread. Use reconnect in another thread to insure a successful cleanup.

先看reconnect代码
使用java-websocket框架开发websocket客户端时遇到的两个问题_第3张图片
然后看reset代码,发现要将读取线程和写出线程都完全关闭。
使用java-websocket框架开发websocket客户端时遇到的两个问题_第4张图片
这里可以看出来,当前执行reconnect的线程如果就是writeThread或者connectReadThread,会抛出这个异常。
使用java-websocket框架开发websocket客户端时遇到的两个问题_第5张图片
原因是,第一张图中的代码:

connectReadThread = new Thread( this );

而connectReadThread执行的代码是:
使用java-websocket框架开发websocket客户端时遇到的两个问题_第6张图片

发现connectReadThread会阻塞在这里,等待连接中的消息。
writeThread同理,会读取写出队列。
在这里插入图片描述
使用java-websocket框架开发websocket客户端时遇到的两个问题_第7张图片
但是由于在onClose前,writeThread已经关闭了,所以reset时已经为null了。
使用java-websocket框架开发websocket客户端时遇到的两个问题_第8张图片

综上所述,如果读取线程和写出线程就是当前执行reset的线程,就不能正常关闭,也就不能reset了。
而在项目中主线程中执行则可以正常使用。
由connectReadThread与writeThread引起的问题就这样解决了。

你可能感兴趣的:(websocket,java,websocket,开发语言)