springboot整合stomp實現 webScoket通訊
阿新 • • 發佈:2020-07-26
1. 官網地址
2.入門示例
本示例在官網示例上稍加修改
2.1 依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
2.2 新增websocket配置類
import org.springframework.context.annotation.Configuration; 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 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic", "/queue"); // 相當於定義了兩個頻道 config.setApplicationDestinationPrefixes("/app"); // 字首 , 與GreetingController類中@MessageMapping值一起使用("/app/hello") config.setUserDestinationPrefix("/queue"); // 表示其中queue這個頻道是用於 一對一發送資訊的. 預設是user } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket") .setAllowedOrigins("*") .withSockJS(); } }
2.3 兩個普通的實體類, 訊息例項
public class Greeting {
private String content;
public Greeting() {
}
public Greeting(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
public class HelloMessage { private String name; public HelloMessage() { } public HelloMessage(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.4 controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.HtmlUtils;
import javax.websocket.server.PathParam;
import java.security.Principal;
import java.time.LocalDateTime;
@RestController
public class GreetingController {
@Autowired
private SimpMessagingTemplate template;
@GetMapping("/sendMsgToUser")
public void sendMsgToUser() {
HelloMessage message = new HelloMessage();
message.setName("鄭欽鋒 to user," + LocalDateTime.now());
// 一對一 [/queue/1/message]
this.template.convertAndSendToUser("1", "/message", message);
}
/**
* client可以直接將訊息傳送到指定的使用者
* DestinationVariable註解與PathVariable功能差不多
* <p>
* 使用 @SendToUser註解將訊息傳送給指定的使用者還沒弄明白, 不然也可以使用註解來實現,省去template
*/
@MessageMapping("/sendMsgToUser/{userId}")
public void sendMsgToUser1(@DestinationVariable("userId") Long userId, HelloMessage message) {
System.out.println(message.getName());
System.out.println(userId);
message.setName("one to one ," + LocalDateTime.now());
this.template.convertAndSendToUser(String.valueOf(userId), "/message", message);
}
/**
* 測試通過SimpMessagingTemplate傳送訊息到"/topic/greetings"頻道
*/
@GetMapping("/sendMsg")
public void sendMsg() {
HelloMessage message = new HelloMessage();
message.setName("鄭欽鋒," + LocalDateTime.now());
// 將資訊傳送到"/topic/greetings"頻道,然後只要是訂閱了此頻道的client都能收到發信息
this.template.convertAndSend("/topic/greetings", message);
}
/**
* 客戶端可以通過@MessageMapping("/hello")[真實需要新增/app字首]這個地址將訊息傳送到 @SendTo("/topic/greetings")這個地址,
* 然後訂閱了/topic/greetings這個地址的客戶端就可以收到訊息
* <p>
* ====================
* 測試通過@SendTo註解傳送訊息到"/topic/greetings"
*/
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting sendMsg1(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
System.out.println(message.getName());
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
2.5 客戶端實現
npm i stompjs -S
npm i sockjs-client -S
import SockJs from 'sockjs-client'
import Stomp from 'stompjs'
//測試websocket 通訊
connect() {
// http://127.0.0.1:8989/api 是服務端根路徑
let socket = new SockJs('http://127.0.0.1:8989/api/gs-guide-websocket');
let stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('連線服務端成功');
console.log('Connected: ' + frame);
// 接收訊息 (客戶端訂閱了"/topic/greetings/")
// stompClient.subscribe('/topic/greetings/', function (greeting) {
// console.log(greeting);
// });
// 傳送訊息到/app/hello
// stompClient.send('/app/hello', {}, JSON.stringify({name: '鄭欽鋒'}),)
// stompClient.send('/app/sendMsgToUser/1', {}, JSON.stringify({name: '鄭欽鋒'}),)
// 接收訊息 (一對一,感覺跟一對多一樣的)
stompClient.subscribe('/queue/1/message', function (greeting) {
console.log(greeting);
});
});
},