关于spring boot+websocket 实现通讯 /websocket 服务端出现软件中止一个已建立连接的解决方法

spring boot  + websocket

首先,pom文件引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>

然后,服务端创建MyWebSocket,因为spring boot提供了@ServerEndpoint注解,大大减少了配置过程。

现在只需要这样实现即可:

@ServerEndpoint("/websocket")
@Component
public class BlockWebSocket {    
//建立连接时会调用此方法
@OnOpen
public void onOpen(Session session){.......};
//连接关闭时会调用此方法
@OnClose
public void onClose(){.....};
//收到客户端消息后调用此方法
@OnMessage
public void onMessage(String message, Session session){....};
//发生错误时会调用此方法
@OnError
public void onError(Session session, Throwable error){...};

//还有一些其他方法,可供业务调用,例如 广播消息等等,详细的可以去查询官网

}

这样服务端的配置就好了。

接下来是前端websocket的配置,通常是在js内配置

let websocket;
if ('WebSocket' in window) {
    console.log("智能节点正在测试链接环境......");
    websocket = new WebSocket("ws://localhost:8082/websocket");
    console.log("webSocket环境正确,正在创建锚点,链接中...");
} else if ('MozWebSocket' in window) {
    console.log("环境异常,无法链接..请确认环境..");
    websocket = new MozWebSocket("ws://echo");
} else {
    console.log("智能节点正在测试链接环境......");
    websocket = new SockJS("http://127.0.0.1:8080/websocket");
    console.log("SockJS环境正确,正在创建锚点,链接中...");
}
websocket.onopen = function (evnt) {
    console.log("链接服务器成功!", evnt.data);
};
websocket.onmessage = function (evnt) {
    console.log('收到消息:', evnt.data);
   
};
websocket.onerror = function (evnt) {
    console.log('出现错误了:'+evnt.data);
};
websocket.onclose = function (evnt) {
        console.log("与服务器断开了链接!")
};

//这些基本配置就不多说了,这里着重描述一个问题

如果按上面这样配置websocket,是可以成功进行通信的,

但是如果创建websocket的页面刷新了或者关闭了,由于websocket的特性,会导致服务端调用关闭websocket,

但是前端的页面在跳转后,其实连接是还在的,所以就会调用到onerror这个方法,出现错误,服务端就会报错。

错误如下:

java.io.IOException: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

Caused by: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

所以,应该控制页面刷新的时候,主动关闭掉此页面的websocket连接。这样就不会提示此错误了。

如何控制?使用js的页面加载刷新的函数即可。如下:

window.onbeforeunload = function(){ websocket.close(); }

这样就解决了如何使服务端不报错的问题。

附:

但是,我想要实现将用户第一次连接的websocket保存下来,不让它断开连接。起初是想把websocket 存进redis内,进行保存。但是发现每次session创建的id都是不同的,无法确定key值,这个想法流产了。

后来,想到一个新思路。使用拦截器,对websocket进行拦截,每次创建新的websocket前,都去redis上扫描一遍,是否该用户已经创建了一个连接,如果已经存在了,那么就把它取出来,而不是重新创建。

但是这个方法还没尝试过。尝试后会再发一篇博文。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值