天天看點

基于websocket-stomp的web-server通訊基于websocket-stomp的web-server通訊

基于websocket-stomp的web-server通訊

新手學習記錄

多個平台都發一哈,怕一個被夾了就莫得了

想實作網頁端和伺服器端的實時雙工通信,采用了websocket-stomp。感覺自己還很不紮實,問題很多。

暫且記錄,有空再好好處理。

目前配置如下:

核心部分

1.伺服器端采用廣播模式,稍微改改就可以實作使用者傳播:

//簡單的連接配接控制
@Controller
@Service
public class StompController {
        //用于計數
	private int i = 0;
	private int j = 0;
	@Autowired
	private SimpMessagingTemplate trafficFlow;
	@Autowired
	private SimpMessagingTemplate peopelFlow;
	//定義了一個服務端接口
	@MessageMapping("/connect")
	@SendTo("/system/msg")
	public void connect(@Payload String name) throws InterruptedException {
		System.out.println("Broadcasting"+"  "+name);
                //當獲得用戶端發送請求時響應
		if(name.equals("iamready")) {
                        //此處進行業務處理
			Random ra = new Random();
			int k = ra.nextInt(100);
			Map<String,Object> msg = new HashMap<String, Object>();
                        //可以不要
			Thread.sleep(1000);
                        //通過SimpMessagingTemplate主動發送消息,而不是利用return,更加靈活
			msg.put(String.valueOf(i), String.valueOf(k));
			trafficFlow.convertAndSend("/system/msg",msg);
			i++;
		}
                //代表用戶端不再需要資訊了,這裡可以處理更好
		if(name.equals("iamfinished")) {
				System.out.println("It is finished");
				i = 0;
			}
	}
        //其他業務省略
        //......
}

           

2.用戶端javaScript部分如下,要實作加載頁面之後自行連接配接伺服器:

//連接配接伺服器
socket = new SockJS('/stomp');
stompClient = Stomp.over(socket);
var data;
//加載頁面就發送請求
set(get);

//關閉頁面就斷開連接配接
window.onbeforeunload = onbeforeunload_handler;
window.onunload = onunload_handler;
function onbeforeunload_handler() {
	sendGoodBye();
	//disconnect();
}

//利用setTimeOut解決異步問題
function set(get){
    stompClient.connect({},function (frame){
    console.log("伺服器連接配接"+frame);
    setTimeout(2000);
    get();
    });	
};

function get(){
    setTimeout(function(){
    stompClient.subscribe('/system/msg', function(mes){
        dataLog = JSON.parse(mes.body);
        console.log(dataLog);
        var temp = Object.keys(dataLog)[0]
        arr.push(dataLog[temp]);
        yarr.push(Object.keys(dataLog)[0]);
        refreshData(arr);//自定義重新整理的時候調用
        stompClient.send("/app/connect",{},"iamready");
    })
    },1000)

setTimeout(function(){stompClient.send("/app/connect",{},"iamready")},1000);
};


//擷取并重新整理資料
function refreshData(data,ydata){
     //重新整理圖表資料
     option = myChart.getOption();
     option.series[0].data = data;
     option.xAxis.data = ydata;
     myChart.setOption(option);    
}
		
//向伺服器發送完成信号
function sendGoodBye(){
    stompClient.send("/app/connect",{},"iamfinished");
}
function disconnect(){
    stompClient.disconnect();
}

           

還有很多地方要改進阿- -

網絡連接配接的安全性問題。

SimpMessagingTemplate類太簡單了

用戶端用setTimeOut太暴力了,最好是利用事件監聽機制進行處理,更加穩健。

目前用戶端邏輯還有點混亂,還得改改- -

對于stomp其他機制了解也不夠多(英文看得腦溢血)。

總之臨時學習還是不太靠譜,有空要認真學。

網絡配置如下:

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;



@Configuration
@EnableWebSocketMessageBroker
//用于實時流 Stomp or websocket的定義,目前暫用stomp
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer{
	//位址
	public static final String BROKER_SYSTEM_MSG = "/system/msg";
	public static final String BROKER_OTHER = "/system";
	public static final String BROKER_PEOPLE = "/system/peopleFlow";
		@Override
	public void configureMessageBroker(MessageBrokerRegistry config) {
			//用于指定用戶端可以訂閱哪些位址
			config.enableSimpleBroker(BROKER_SYSTEM_MSG,BROKER_PEOPLE);
			//用戶端發送消息的服務端位址字首
			config.setApplicationDestinationPrefixes("/app");
			//服務端發給 制定 用戶端的字首 /system/msg 是廣播 /user/system/msg則是制定用戶端
			config.setUserDestinationPrefix("/user");
		}
	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		//SockJS 用于定義連接配接節點
		registry.addEndpoint("/stomp")//.setHandshakeHandler(new CustomHandler())
			//.setAllowedOrigins("*")
			.withSockJS();		
	}
	//配置線程數量(pool),防止錯順序
	@Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(1).maxPoolSize(1);
    }	
}

           

部分pom.xml如下:

<dependency>
 			<groupId>org.webjars</groupId>
  			<artifactId>sockjs-client</artifactId>
  			<version>1.0.2</version>
		</dependency>
		<dependency>
 	 		<groupId>org.webjars</groupId>
  			<artifactId>stomp-websocket</artifactId>
  			<version>2.3.3</version>
		</dependency>
		<dependency>
  			<groupId>org.webjars</groupId>
  			<artifactId>bootstrap</artifactId>
  			<version>3.3.7</version>
		</dependency>
		<dependency>
  			<groupId>org.webjars</groupId>
  			<artifactId>jquery</artifactId>
  			<version>3.1.1-1</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			</dependency>

           

初學者,希望各位大佬不吝賜教!