记websocket遇到的问题以及解决方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记websocket遇到的问题以及解决方法相关的知识,希望对你有一定的参考价值。

参考技术A         在本文中我使用的websocket框架是FaceBook提供的SocketRocket框架,在此不再为此进行过多的介绍,网上websocket介绍很全,如: SRWebSocket源码浅析  ,还有理解websocket的文章: WebSocket原理  等。本文着重叙述在使用WebSocket与服务器对接时遇到的问题。

        1、连接失败,错误信息:  Error Domain=NSPOSIXErrorDomain Code=61 "Connection refused" UserInfo=_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1

        解析:61错误是:服务器端口没打开

        解决办法:检查服务器是否开启端口。若服务器使用的是别人的服务器,使用各种抓包软件抓一下是否在连接websocket前使用post或者get方法请求一遍,模拟一下发送的参数,看看是否将其端口开启。

        2、连接成功,立刻断开,断开信息: code:1001 reason :Stream end encountered wasclean:0

        解析:1001,表示“离开”(going away),例如服务器关闭或浏览器导航到其他页面

        解决办法:检查socket初始化方法,与socket协议进行比较(抓包连接情况),使用

- (id)initWithURLRequest:(NSURLRequest*)request protocols:(NSArray*)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates; 方法初始化socket对象。在protocols数组中装着协议内容,如:_protocolsArray = @[@"XXX"]; 其中,XXX为抓包出来的protocol内容,如图所示:

        3、连接成功,有收到心跳信息,然后断开,断开信息: code:1001 reason :Stream end encountered wasclean:0

        解析:1001,离开。在收到心跳包的情况下,出现断开,这种情况只有服务器发送心跳包给你,你没有回复服务器,服务器默认你离开了。

        解决方法:回复心跳包给服务器,心跳包一问一答的对话方式保持socket连接。

        至此,前两个小问题都解决好了,这两个小问题卡了我快一周的时间,记录一下。

参考文档: WebSocket关闭连接

                     WebSocket_API的使用

小结java使用Websocket获取HttpSession出现的问题

websocket的写法就不多说了,主要记一记其中出现的问题

1.获取不到httpSession

解决办法:先重写握手方法,将httpsession放入ServerEndpointConfig.getUserProperties()方法返回的map中

 1 import javax.servlet.http.HttpSession;
 2 import javax.websocket.HandshakeResponse;
 3 import javax.websocket.server.HandshakeRequest;
 4 import javax.websocket.server.ServerEndpointConfig;
 5 import javax.websocket.server.ServerEndpointConfig.Configurator;
 6 
 7 /**
 8  * 继承websocket配置类,将httpsession放入ServerEndpointConfig的map中
 9  * 从而达到使websocket对象可以访问到httpsession中的对象
10  */
11 public class GetHttpSessionConfigurator extends Configurator{
12 
13     /**
14      * 重写修改握手方法
15      * @param sec
16      * @param request
17      * @param response
18      */
19     @Override
20     public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
21         HttpSession httpSession = (HttpSession)request.getHttpSession();
22         sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
23     }
24 }

然后在注解@ServerEndpoint加入configurator的配置

 1 @ServerEndpoint(value="/websocket",configurator=GetHttpSessionConfigurator.class) 

此时已经可以获取到httpsession了。

然而如果我没有登录,反而需要临时登录这种情况呢?根据上述demo,会发现根本没办法连接上,一直是close状态

下面是对这个问题的解决

2、未登录用户连接WebSocket,一直close状态的情况解决:

解决方法是建立个请求监听器
 1 @WebListener
 2 public class RequestListener implements ServletRequestListener {
 3     
 4     public void requestInitialized(ServletRequestEvent sre)  { 
 5         //将所有request请求都携带上httpSession
 6         ((HttpServletRequest) sre.getServletRequest()).getSession();
 7         
 8     }
 9     public RequestListener() {
10         // TODO Auto-generated constructor stub
11     }
12 
13     public void requestDestroyed(ServletRequestEvent arg0)  { 
14          // TODO Auto-generated method stub
15     }
16 }

问题解决。

以上是关于记websocket遇到的问题以及解决方法的主要内容,如果未能解决你的问题,请参考以下文章

记一个nacos/openfeign遇到的问题,找到解决方法,但是不知原因

记一个nacos/openfeign遇到的问题,找到解决方法,但是不知原因

记 K8s 集群中 Flannel 遇到的两个问题

第1415教学周作业

记mysql8.0.20下载安装以及遇到的问题

记程序员生涯中第一次遇到内存溢出错误