1.引入websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
2.将websocket相关服务交给spring管理
public class MySpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
private static volatile ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MySpringConfigurator.context=applicationContext;
}
@Override
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
return context.getBean(clazz);
}
}
3.websocket配置
@Configuration
@ConditionalOnWebApplication
public class WebSocketConfig {
/**
* 注入对象ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
*/
@Bean
public ServerEndpointExporter getServerEndpointExporter(){
return new ServerEndpointExporter();
}
@Bean
public MySpringConfigurator getSpringConfigurator(){
return new MySpringConfigurator();
}
}
4.配置WebSocketEndPoint(其实就是配置Controller差不多,支持restApi)
@Component
@ServerEndpoint(value = "/mywebsocket/{openId}",configurator = MySpringConfigurator.class)
public class MyWebSocketEndPoint {
//当前会话
private Session session;
private static int onlineCount;
private static Map<String,MyWebSocketEndPoint> webSocketEndPointMap=new ConcurrentHashMap<String,MyWebSocketEndPoint>();
@OnOpen
public void onOpen(@PathParam(value="openId") String openId , @PathParam(value="role") String role , Session session){
if( webSocketEndPointMap.containsKey(openId)){
MyWebSocketEndPoint myWebSocketEndPoint=webSocketEndPointMap.get(openId);
this.session=myWebSocketEndPoint.session;
return;
}
webSocketEndPointMap.put("openId",this);
this.session=session;
this.addOnlineCount();
}
@OnClose
public void onClose(Session session){
webSocketEndPointMap.remove(this);
this.subOnlineCount();
}
@OnError
public void onError(Throwable throwable,Session session){
System.err.println("error heppenning");
throwable.printStackTrace();
}
@OnMessage
public void onMessage(String msg){
System.out.println(msg);
sendMsg(msg);
}
private void sendMsg(String msg){
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
public static synchronized int getOnlineCount(){
return onlineCount;
}
public static synchronized void addOnlineCount(){
onlineCount++;
}
public static synchronized void subOnlineCount(){
onlineCount--;
}
}
5.前端配置
var lockReconnect = false;//避免重复连接
var wsUrl = "ws://192.168.3.207:80/mywebsocket/{aaaa}";
var ws;
createWebSocket();
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
alert("it error");
console.log('catch'+e);
reconnect(wsUrl);
}
}
function init() {
ws.onclose = function () {
console.log('链接关闭');
reconnect(wsUrl);
};
ws.onerror = function() {
console.log('发生异常了');
reconnect(wsUrl);
};
ws.onopen = function () {
console.log('建立连接');
ws.send(JSON.stringify({"doWhat":"getLink"}));
//心跳检测重置
heartCheck.start();
};
ws.onmessage = function (event) {
console.log('接收到消息'+event.data);
heartCheck.start();
//拿到任何消息都说明当前连接是正常的
}
}
var lockReconnect = false;//避免重复连接
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 40000);
}
//心跳检测
var heartCheck = {
timeout: 60000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
console.log('start');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
console.log('55555');
ws.send(JSON.stringify({"doWhat":"testLink"}));
self.serverTimeoutObj = setTimeout(function() {
console.log(111);
console.log(ws);
ws.close();
// createWebSocket();
}, self.timeout);
}, this.timeout)
}
}
网友评论