天天看點

Sping WebSocket SockJS使用注意點:

注意點:

1、Spring Framework從4.0版本開始支援websocket,示例代碼使用的是4.1.3

2、SockJs是一個封裝的WebSocket實作,可以支援低版本的IE浏覽器。

3、SockJs+Spring-WebSocket時,由于SockJs與Spring WebSocket之間采用JSON通訊,需要引入jackson 2的相關jar包。

4、項目需要使用到Spring MVC。

具體代碼實作(小例子):

1、Spring WebSocket配置類

package com.watcher.websocket.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration  //配置類
@EnableWebSocket  //聲明支援websocket
public class WebSocketConfig implements WebSocketConfigurer{

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

		//注冊websocket實作類,指定參數通路位址;allowed-origins="*" 允許跨域
		registry.addHandler(myHandler(), "/ws").addInterceptors(myHandshake()).setAllowedOrigins("*");
		//允許用戶端使用SockJS
		registry.addHandler(myHandler(), "/sockjs/ws").addInterceptors(myHandshake()).withSockJS();
	}
	
	@Bean
	public MyHandler myHandler(){
		return new MyHandler();
	}

	@Bean
	public MyHandshakeInterceptor myHandshake(){
		return new MyHandshakeInterceptor();
	}
	

}
           

2、Handler類實作(用于處理具體的消息)

package com.watcher.websocket.spring;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

//extending either TextWebSocketHandler orBinaryWebSocketHandler
public class MyHandler implements WebSocketHandler {
	
	

	@Override
	public void afterConnectionClosed(WebSocketSession arg0, CloseStatus arg1) throws Exception {
		// TODO Auto-generated method stub
		
		System.out.println("Connection closed..."+arg0.getRemoteAddress().toString());
		
	}

	@Override
	public void afterConnectionEstablished(WebSocketSession arg0) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Connection established..."+arg0.getRemoteAddress().toString());
	}

	@Override
	public void handleMessage(WebSocketSession arg0, WebSocketMessage<?> arg1) throws Exception {
		// TODO Auto-generated method stub
	     try {
	    	 System.out.println("Req: "+arg1.getPayload());
			TextMessage returnMessage = new TextMessage(arg1.getPayload()  
				      + " received at server");  
			 arg0.sendMessage(returnMessage);
		} catch (Exception e) {
			e.printStackTrace();
		}  
	}

	@Override
	public void handleTransportError(WebSocketSession arg0, Throwable arg1) throws Exception {
		// TODO Auto-generated method stub
		if(arg0.isOpen()){
			arg0.close();
		}
		System.out.println(arg1.toString());
		System.out.println("WS connection error,close...");
	}

	@Override
	public boolean supportsPartialMessages() {
		// TODO Auto-generated method stub
		return false;
	}

	
	
}
           

 3、握手攔截器實作(攔截器...)

package com.watcher.websocket.spring;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

/**
 * 
 * 類描述:握手攔截器
 * com.watcher.websocket.spring  MyHandshakeInterceptor
 * Created by 78098 on 2016年11月15日.
 * version 1.0
 */
public class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor{

	@Override
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
		// TODO Auto-generated method stub
		System.out.println("After handshake "+request.getRemoteAddress().toString());
		super.afterHandshake(request, response, wsHandler, ex);
	}

	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Before handshake "+request.getRemoteAddress().toString());
		return super.beforeHandshake(request, response, handler, map);
	}

	
	
}
           

 4、頁面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./plugin/sockjs/sockjs-1.1.1.js"></script>
<script type="text/javascript">
	var url = "192.168.120.37:8080/springMybatis";
	var websocket = null;
	if ('WebSocket' in window) {
		websocket = new WebSocket("ws://" + url + "/ws");
	} else {
		websocket = new SockJS("http://" + url + "/sockjs/ws");
	}
	websocket.onopen = onOpen;
	websocket.onmessage = onMessage;
	websocket.onerror = onError;
	websocket.onclose = onClose;

	function onOpen(openEvent) {
		document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ "OPEN<br/>";
	}

	function onMessage(event) {
		document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ event.data+"<br/>";
	}
	function onError() {
	}
	function onClose() {
		document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ "CLOSE<br/>";
	}

	function doSend() {
		console.log(websocket.readyState);
		if (websocket.readyState == SockJS.OPEN) {
			var msg = document.getElementById("message").value;
			websocket.send(msg);
		} else {
			alert("連接配接失敗!");
		}
	}
	
	
	function disconnect(){
		if (websocket != null) {
			websocket.close();
			websocket = null;
        }
	}
	
	function reconnect(){
		if (websocket != null) {
			websocket.close();
			websocket = null;
        }
		if ('WebSocket' in window) {
			websocket = new WebSocket("ws://" + url + "/ws");
		} else {
			websocket = new SockJS("http://" + url + "/sockjs/ws");
		}
		websocket.onopen = onOpen;
		websocket.onmessage = onMessage;
		websocket.onerror = onError;
		websocket.onclose = onClose;
	}
</script>
</head>
<body>
	<div>
		<button id="disconnect" οnclick="disconnect()">斷開連接配接</button>
		<button id="send" οnclick="doSend()">發送消息</button>
		<button id="reconnect" οnclick="reconnect()">重新連接配接</button>
	</div>
    <div>
       <textarea id="message" style="width: 350px">Here is a message!</textarea>
    </div>
    <div>日志資訊:</div>
	<p id="console" width="600px"></p>
</body>
</html>