Unable to unwrap data, invalid status [CLOSED]-服务端webSocket报错


一、问题由来

现在的项目中在使用webSocket这门技术,主要用来在服务端和客户端进行实时的数据传输,因为需要及时的进行响应,所以才没有使用http请求的方式,

而是使用socket的方式,这样可以快速建立起连接,并且能够将小程序端的操作实时的在客户端unity程序中进行响应。最开始做这个项目的时候,自己对

于技术选型这一块,就考虑使用webSocket,经常会在各种博客、论坛中看到关于它的介绍和使用。而且给人的感觉不是太难,因此就打算使用它。客户端

程序主要是unity程序来进行处理,会和java写的服务端进行实时通信传输很多数据,在刚开始测试的阶段我们都不知道这种方案能不能行得通,在经过多次

反复地测试之后,发现这种方式可行,最终采用这门技术应用于现在的系统当中。可是后来在使用的过程中出现一个问题,就是当webSocket运行出现异常,

比如客户端和服务端的连接由于网络不好断开之后,当网络恢复正常再次进行连接时就会频繁报错,

 报错信息是客户端发送的心跳包数据,由于客户端不知道服务端已经出现问题,因此频繁的发送心跳包就一直报错。

二、问题分析

自己在写服务端时,当运行onError方法时,会清除一个唯一的webSocket连接,由于这个项目的特殊性,只需要始终让服务端和客户端保持有一个有效的连接

即可。自己的想法是,明明已经清楚了服务端唯一的连接,为什么还会出现这种问题呢?

 这个问题隔三差五的就会出现,必须要解决,如果不解决的话肯定会影响项目的正常运行。

三、解决方案

进过对问题的仔细分析后,自己尝试着去解决这个问题,一个一个地进行尝试。

方案一:在运行出错的时候,主动调用webSocket中提供的关闭连接的方法,使用this来进行调用。

 测试结果,没有解决。

方案二:在运行出错的时候,主动获取集合里面的那个唯一的webSockerServer对象,然后使用这个对象来调用onClose方法,并且关闭当前的连接

会话session。

 代码修改好之后,和客户端进行反复的联调测试,发现问题解决。解决这个问题的思路就是,如果服务端运行出现异常,就在服务端主动

关闭这个连接;当这个连接关闭之后,当客户端和服务端想再次进行通信时,就会重新创建一个新的连接,保重系统的正常运行。

至此问题解决,可能也是这个项目的特殊性才导致这个项目只需要有一个唯一的连接就可以,遇到的问题也比较好解决。总结一下就是如果

服务端想关闭掉某个连接,则最好是先找到这个webSocket这个连接,然后关闭即可,还有关闭当前的会话信息,不能使用集合直接清除,

直接清除结合的话,webSocketServer是清除了,可是连接会话信息却还在,因此导致我出现那个问题。