springboot中使用websocket

2 篇文章 1 订阅
1 篇文章 0 订阅

websocket实现一:

使用springboot的配置,实现websocket服务端,需要导入spring websocket的依赖

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

 创建websocket的配置

@Configuration  
@EnableWebSocket  
public class WebSocketConfig implements WebSocketConfigurer {  
    @Override  
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
        registry.addHandler(orderHandler(),"/orderWSServer")
        .addInterceptors(new OrderInterceptor()).setAllowedOrigins("*");
    }  
   
    @Bean  
    public TextWebSocketHandler orderHandler(){  
        return new OrderHandler();  
    }  
  
}

这里需要配置handler与一个拦截器

public class OrderHandler extends TextWebSocketHandler{
	public static final HashMap<String, WebSocketSession> userSessionMap;
	 
	 
    static {  
        userSessionMap = new HashMap<>();
    }  
  
    /** 
     * 连接成功时候,会触发UI上onopen方法 
     */  
    @Override  
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {  
        System.out.println("connect to the websocket success......");  
        Map<String, Object> attributes = session.getAttributes();
        String userCode = (String) attributes.get("userCode");
        if(userCode != null) {
        	userSessionMap.put(userCode, session);
        }
    }  
  
    /** 
     * 在UI在用js调用websocket.send()时候,会调用该方法 
     */  
    @Override  
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {  
        sendMessageToUsers(message);  
    }  
  
    /** 
     * 给某个用户发送消息 
     * 
     * @param userName 
     * @param message 
     */  
    public void sendMessageToUser(String userName, TextMessage message) {  
    }  
  
    /** 
     * 给所有在线用户发送消息 
     * 
     * @param message 
     */  
    public void sendMessageToUsers(TextMessage message) {  
    }  
  
    @Override  
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {  
        if (session.isOpen()) {  
            session.close();  
        }
        Map<String, Object> attributes = session.getAttributes();
		String userCode = (String) attributes.get("userCode");
		if(userCode != null) {
			userSessionMap.remove(userCode);
		}
    }  
  
    @Override  
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		Map<String, Object> attributes = session.getAttributes();
		String userCode = (String) attributes.get("userCode");
		if(userCode != null) {
			userSessionMap.remove(userCode);
		}
    }  
  
    @Override  
    public boolean supportsPartialMessages() {  
        return false;  
    }  
}
public class OrderInterceptor extends HttpSessionHandshakeInterceptor {  
	  
    @Override  
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,  
            Map<String, Object> attributes) throws Exception {  
       System.out.println("Before Handshake");
       String userCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("userCode");
       System.out.println(userCode);
       
        attributes.put("userCode", userCode);  
  
        return super.beforeHandshake(request, response, wsHandler, attributes);  
    }  
  
    @Override  
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,  
            Exception ex) {  
        System.out.println("After Handshake");  
        super.afterHandshake(request, response, wsHandler, ex);  
    }  
  
} 

这里interceptor中可以获取到请求中的信息,在客户端中websocket连接可以携带请求参数。

在js客户端发送请求,增加心跳机制,防止nginx自动断开连接

        var heartCheck = {
		timeout: 20000,
		timeoutObj: null,
		serverTimeoutObj: null,
		reset: function(){
			clearTimeout(this.timeoutObj);
			clearTimeout(this.serverTimeoutObj);
			return this;
		},
		start: function(){
			var self = this;
			this.timeoutObj = setTimeout(function(){
				//这里发送一个心跳,后端收到后,返回一个心跳消息,
				//onmessage拿到返回的心跳就说明连接正常
				websocket.send("HeartBeat" + new Date());
				console.info("客户端发送心跳:" + new Date());
				self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
					websocket.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
				}, self.timeout)
			}, this.timeout)
		}
	}            
        var userCode = $("input[name='userCode']").val();
		
	    //判断当前浏览器是否支持WebSocket
	    if ('WebSocket' in window) {
	        websocket = new WebSocket("ws://192.168.160.152:7003/ycService/orderWSServer?userCode="+userCode);
	    }
	    else {
	        alert('当前浏览器 Not support websocket')
	    }


	    //连接发生错误的回调方法
	    websocket.onerror = function () {
	        setMessageInnerHTML("WebSocket连接发生错误");
	    };


	    //连接成功建立的回调方法
	    websocket.onopen = function () {
            //如果获取到消息,心跳检测重置
		heartCheck.reset().start();
	        setMessageInnerHTML("WebSocket连接成功");
	    }


	    //接收到消息的回调方法
	    websocket.onmessage = function (event) {
	        setMessageInnerHTML(event.data);
			console.log(event);
	    }


	    //连接关闭的回调方法
	    websocket.onclose = function () {
	        setMessageInnerHTML("WebSocket连接关闭");
	    }
		//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
	    window.onbeforeunload = function () {
	        closeWebSocket();
	    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值