springboot的websocket因IP问题无法连接
首先遇到这个问题有点奇葩,出现在项目上线时的客户现场,头两天一直都无法确定原因,因为它的表现方式很奇怪,基于springboot实现的websocket,同样的代码在公司研发环境不会有问题,客户现场会出现浏览器一连接就马上断开,没有使用任何代理服务器,服务器没有任何异常,就是浏览器直接断开,最后排除现场环境和公司环境差异性,不断保持两边的一直性,最有可能的一项,能想到的人不多了,IP地址不一样,我一开始是不相信的,IP地址不一样会导致这种问题?
我注重测试验证理论,试一把再说,结果就可以了,同样的服务器在192.168.x.x这种网段下不会有问题,如果是34.69.x.x这种短IP就不行,本人对网络不是很了解,同样的服务器和一模一样的代码,仅仅一个IP不同就会造成websocket无法使用吗?我知道的方法和网上的参考资料全部试了一下,无法解决,如果有知道的朋友可以留言。
此路不同就换一条路,我决定放弃springboot的websocket实现,尝试tomcat服务器的websocket实现,解决了此问题。
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
java代码
import com.bootdo.common.utils.JSONUtils;
import com.bootdo.system.domain.UserDO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint(value = "/endpointChat", configurator=GetHttpSessionConfigurator.class)
@Component
public class WebSocketSession {
private static final Logger logger = LoggerFactory.getLogger(WebSocketSession.class);
private static Map<String, WebSocketSession> clients = new ConcurrentHashMap<String, WebSocketSession>();
private Session session;
private String userSessionId;
private static String mark = "_";
private static String destinationPrefix = "/user";
private List<String> theme = new ArrayList<>();
@OnOpen
public void onOpen(Session session,EndpointConfig config) {
HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); SimplePrincipalCollection principalCollection = (SimplePrincipalCollection) httpSession
.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
UserDO userDO = (UserDO) principalCollection.getPrimaryPrincipal(); session.setMaxTextMessageBufferSize(1024 * 100 * 5);
session.setMaxBinaryMessageBufferSize(1024 * 100 * 5);
this.userSessionId = userDO.getUserId().toString()+mark+session.getId();
this.session = session;
clients.put(this.userSessionId, this);
} @OnClose
public void onClose(Session session) {
try {
clients.remove(userSessionId);
}catch (Exception e){
logger.error(e.getMessage(),e);
}
} @OnError
public void onError(Session session, Throwable error) {
clients.remove(userSessionId);
try {
session.close();
} catch (IOException e) {
logger.error("close session failed {}", e.getMessage());
}
} /**
* 收到客户端消息后调用的方法
* @param message
*/
@OnMessage
public void onMessage(String message, Session session) {
SimpleTextMsg msgObj = JSONUtils.jsonToBean(message, SimpleTextMsg.class);
if(msgObj.getOption().equals(WebSocketClientOption.REGISTER_THEME)){//client在连接成功之后,注册监听主题
theme.add(msgObj.getTheme());
}
} public static void convertAndSendToUser(String userId, String theme, String jsonData) {
synchronized (userId.intern()){
try{
for (WebSocketSession item : clients.values()) {
String idKey = userId+mark+item.getUserSessionId().split(mark)[1];
if (item.getUserSessionId().equals(idKey)){
if(item.getTheme().contains(destinationPrefix+theme)){//判断该session的用户是否订阅主题
SimpleTextMsg textMsg = new SimpleTextMsg();
textMsg.setBody(jsonData);
textMsg.setTheme("/user"+theme);
item.session.getBasicRemote().sendText(JSONUtils.beanToJson(textMsg));
}
}
}
}catch (Exception e){
logger.error(e.getMessage(),e);
}
}
} public String getUserSessionId() {
return userSessionId;
} public void setUserSessionId(String userSessionId) {
this.userSessionId = userSessionId;
} public List<String> getTheme() {
return theme;
} public void setTheme(List<String> theme) {
this.theme = theme;
} public static Map<String, WebSocketSession> getClients() {
return clients;
}
}
html5_websocket.js 核心方法
//开始之前请引入reconnecting-websocket.js
var ipRe=/^(\d+)\.(\d+)\.(\d+)\.(\d+).*$/;//正则表达式
function SxpSockJS(url){
this.host = window.location.host; if(ipRe.test(url)){
this.url = url;
}else if(url.indexOf("http") == 0 || url.indexOf("https") == 0){
this.url = url.splice("//")[1];
}else{
this.url = this.host + url;
}
console.log("connection url:"+this.url);
this.websocket = null;
this.subscribe = function(theme, callBack){//theme订阅主题,callBack回调函数
this.websocket.themeMap[theme] = callBack;
this.websocket.send("{theme:'"+theme+"',option:'registerTheme'}");
};
this.connect = function(onOpen,onError){
this.websocket = new ReconnectingWebSocket("ws://"+this.url,null,{reconnectInterval: 3000});
this.websocket.themeMap = {};
this.websocket.timeoutInterval = 5400;
this.websocket.onopen = function(event){
console.log("漂亮!与服务器websocket连接成功!!!");
if(onOpen && typeof onOpen === "function")onOpen();
};
this.websocket.onclose = function(event){
console.log("悲剧!与服务器websocket连接断开!!!");
if(onError && typeof onOpen === "function")onError();
};
this.websocket.onmessage = function (data) {
console.log(data.timeStamp+"<<< CONNECTED");
var obj = eval('(' + data.data + ')');
var callBack = this.themeMap[obj.theme];
if(callBack){
console.log("theme:"+obj.theme);
console.log("jsonData:"+obj.body);
callBack(obj);
}
console.log(data.timeStamp+"<<< END");
console.log(" ");
}
}
}
js调用代码
function init() {
var sock = new SxpSockJS(ctx+"endpointChat");
sock.connect(function() {//异步
sock.subscribe("/user/queue/prisoncellOnLine", handleNotification);
sock.subscribe("/user/queue/prisoncellAreaWarn", personAreaWarn);
sock.subscribe("/user/queue/prisoncellOffLine", personOffLine);
sock.subscribe("/user/queue/personSignEnd", personSignEnd);
sock.subscribe("/user/queue/personSignStart", personSignStart);
sock.subscribe("/user/queue/prisoncellFlush",prisoncellFlush);
},function(){
//异常处理逻辑
});
}
这里用到了一个websocket重连的函数,需要下载一个js,reconnecting-websocket.min.js
springboot的websocket因IP问题无法连接的更多相关文章
- 基于springboot的websocket聊天室
WebSocket入门 1.概述 1.1 Http #http简介 HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. #http1.0/1.1/2.0 1.HTT ...
- SpringBoot+Vue+WebSocket 实现在线聊天
一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二 ...
- WebSocket的简单认识&SpringBoot整合websocket
1. 什么是WebSocket?菜鸟对websocket的解释如下 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务 ...
- Springboot整合Websocket遇到的坑
Springboot整合Websocket遇到的坑 一.使用Springboot内嵌的tomcat启动websocket 1.添加ServerEndpointExporter配置bean @Confi ...
- SpringBoot 整合 WebSocket
SpringBoot 整合 WebSocket(topic广播) 1.什么是WebSocket WebSocket为游览器和服务器提供了双工异步通信的功能,即游览器可以向服务器发送消息,服务器也可以向 ...
- SpringBoot集成WebSocket【基于纯H5】进行点对点[一对一]和广播[一对多]实时推送
代码全部复制,仅供自己学习用 1.环境搭建 因为在上一篇基于STOMP协议实现的WebSocket里已经有大概介绍过Web的基本情况了,所以在这篇就不多说了,我们直接进入正题吧,在SpringBoot ...
- SpringBoot基于websocket的网页聊天
一.入门简介正常聊天程序需要使用消息组件ActiveMQ或者Kafka等,这里是一个Websocket入门程序. 有人有疑问这个技术有什么作用,为什么要有它?其实我们虽然有http协议,但是它有一个缺 ...
- springboot整合websocket原生版
目录 HTTP缺点 HTTP websocket区别 websocket原理 使用场景 springboot整合websocket 环境准备 客户端连接 加入战队 微信公众号 主题 HTTP请求用于我 ...
- 使用springboot+layim+websocket实现webim
使用springboot+layim+websocket实现webim 小白技术社 项目介绍 采用springboot和layim构建webim,使用websocket作为通讯协议,目前已经能够正 ...
- springboot集成websocket的两种实现方式
WebSocket跟常规的http协议的区别和优缺点这里大概描述一下 一.websocket与http http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能 ...
随机推荐
- php 虚拟化 linux 入侵检测交作业 不要太nice
#inclide<iostream> using namespace std; int main() { cout<<"暂时自闭一会er"; }
- Java数组之什么是数组?+ 数组的声明和创建
数组 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排序组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组声明创建 首先 ...
- chrome 请停用以开发者
链接:https://pan.baidu.com/s/1YhWINGlUVyTE5XyBVIGW_Q 提取码:23t2 转载至 https://www.cnblogs.com/it-tsz/p/9 ...
- JavaScript Math(算数) 对象
JavaScript Math(算数) 对象 Math(算数)对象的作用是:执行常见的算数任务. 在线实例 round()如何使用 round(). random()如何使用 random() 来返回 ...
- java中获取指定日期是周几
可以使用Calendar日历工具类获取,代码如下: Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); ...
- linux(centos7)下部署jenkins
1.安装jdk yum install -y java 确保已经安装了jdk,查看是否安装jdk命令参考地址: 2.安装jenkins 2.0添加Jenkins库到yum库,Jenkins将从这里下载 ...
- ZSTUOJ刷题12:Problem B.--深入浅出学算法007-统计求和
Problem B: 深入浅出学算法007-统计求和 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 6782 Solved: 3693 Descript ...
- vscode python配置pip源
更换到国内清华园 C盘-User-用户名-新建"pip"文件夹-新建"pip.ini"文件 pip.ini 文件中内容: [global]index-url = ...
- XSS跨站脚本攻击(Cross Site Scripting)
XSS是跨站脚本攻击(Cross Site Scripting),不写为CSS是为了避免和层叠样式表(Cascading Style Sheets)的缩写混淆,所以将跨站脚本攻击写为XSS. 攻击者可 ...
- 浏览器垃圾回收机制:栈垃圾回收、堆垃圾回收、新生区老生区、Scavenge算法、标记-清除算法、标记-整理算法、全停顿、增量标记
浏览器垃圾回收机制根据数据的存储方式分为栈垃圾回收和堆垃圾回收. 栈垃圾回收的方式非常简便,当一个函数执行结束之后,JavaScript 引擎会通过向下移动 ESP 来销毁该函数保存在栈中的执行上下文 ...