基于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>
初學者,希望各位大佬不吝賜教!