您好,登錄后才能下訂單哦!
今天小編就為大家帶來一篇使用SpringBoot和WebSocket實現簡易聊天室的文章。小編覺得挺不錯的,為此分享給大家做個參考。一起跟隨小編過來看看吧。
①:什么是 WebSocket?
WebSocket 是一種在單個 TCP 連接上進行全雙工通信的協議
根據這個定義有兩個注意的地方:
協議就是相互通信的計算機雙方必須共同遵守的一組約定。
1)HTTP協議基于 TCP 協議,建立鏈接必須通過三次握手才能發送信息。
2)http鏈接分為短鏈接,長鏈接,短鏈接是每次請求都要三次握手才能發送自己的信息。即每一個request 對應一個 response。長鏈接是在一定的期限內保持鏈接。保持TCP連接不斷開。客戶端與服務器通信,必須要有客戶端發起然后服務器返回結果。客戶端是主動的,服務器是被動的。
3)WebSocket 他是為了解決客戶端發起多個 http 請求到服務器資源瀏覽器必須要經過長時間的輪訓問題而生的,他實現了多路復用,他是全雙工通信。在 webSocket 協議下客服端和瀏覽器可以同時發送信息。
@Configuration
@EnableWebSocketMessageBroker //通過此注解開啟 WebSocket 消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
//設置消息代理的前綴
// 如果消息的前綴是 /topic 就會將消息轉發給消息代理(broker)再由消息代理轉發給所有連接的客戶端
config.enableSimpleBroker("/topic"); //客戶端接收服務端消息的地址前綴
//配置一個或多個前綴,通過這些前綴過濾出需要被注解方法處理的消息。
// 例如前綴為"/app"的 destination 可以通過 @MessageMapping 注解的方法處理,而其他 destination("/topic","/query") 將被直接交給 broker 處理
config.setApplicationDestinationPrefixes("/app"); //客戶端給服務端發消息的地址前綴
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//定義一個前綴為 "chat" 的endpoint,并開啟 sockJs支持。
// sockJs 可以解決對 WebSocket 的兼容性問題,客戶端將通過這里配置的 url 建立 WebSocket 連接
registry.addEndpoint("/chat").withSockJS();
}
}
@Controller
public class GreetingController {
/**
* 執行步驟:
* 1,由 WebSocketConfig 中的配置,@MessageMapping 注解接收 "/app/hello" 路徑發來的消息
* 2,注解方法對消息進行處理后,將消息轉發到 @SendTo 定義的路徑上
* 3,@SendTo 定義的路徑是一個前綴為 "/topic" 的路徑,由配置文件,此消息將被交給消息代理 broker,由 broker 進行廣播
* @param message
* @return
*/
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Message greeting(Message message) {
return message;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>群聊</title>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="/app.js"></script>
</head>
<body>
<div>
<label for="name">請輸入用戶名</label>
<input type="text" id="name" placeholder="用戶名">
</div>
<div>
<button id="connect"type="button">連接</button>
<button id="disconnect"type="button" disabled="disabled">斷開連接</button>
</div>
<div id="chat" >
<div>
<label for="name">請輸入聊天內容</label>
<input type="text" id="content" placeholder="聊天內容">
</div>
<button id="send" type="button">發送</button>
<div id="greetings">
<div id="conversation" >群聊進行中</div>
</div>
</div>
</body>
</html>
var stompClient = null;
//頁面顯示設置
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
$("#chat").show();
} else {
$("#conversation").hide();
$("#chat").hide();
}
$("#greeting").html("");
}
//建立一個 WebSocket 連接,建立連接之前必須輸入用戶名
function connect() {
if (!$("#name").val()) {
return;
}
//創建一個 SockeJS 實例
var socket = new SockJS('/chat');
//使用stomp.over方式創建一個stompClient,完成客戶端的創建。
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
//進行頁面設置
setConnected(true);
//使用 subscribe 方法訂閱服務端發送回來的消息,并將服務端發送的消息展示出來
stompClient.subscribe('/topic/greetings', function (greetings) {
showGreeting(JSON.parse(greetings.body));
})
})
}
//斷開 WebSocket 連接
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false)
}
//發送信息
function sendName() {
stompClient.send("/app/hello", {},
JSON.stringify({'name': $('#name').val(), 'content': $('#content').val()}));
}
//展示信息
function showGreeting(message) {
$('#greetings')
.append("<div>" + message.name + ":" + message.content + "</div>")
}
$(function () {
//建立連接
$("#connect").click(function () {
connect();
});
//斷開連接
$("#disconnect").click(function () {
disconnect();
});
//發送信息
$("#send").click(function () {
sendName();
});
})
1)maven 引入依賴錯誤(盡量去 maven 的中央倉庫拷貝依賴)
2)stomp 協議的引入
使用STOMP的好處在于,它完全就是一種消息隊列模式,你可以使用生產者與消費者的思想來認識它,發送消息的是生產者,接收消息的是消費者。而消費者可以通過訂閱不同的destination,來獲得不同的推送消息,不需要開發人員去管理這些訂閱與推送目的地之前的關系。
案例見spring官網就有一個簡單的spring-boot的stomp-demo,如果是基于springboot,大家可以根據spring上面的教程試著去寫一個簡單的demo。
/**
* 1. @MessageMapping("/hello") Spring提供一個 @MessageMapping 注解實現了對 WebScoket 的封裝
* 2. SimpMessagingTemplate 是 Spring-WebSocket 內置的一個消息發送的工具
* @param message
* @throws Exception
*/
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/hello")
public void greeting(Message message) throws Exception{
//使用這個方法進行消息的轉發發送
simpMessagingTemplate.convertAndSend("/topic/greetings",message);
}
剛剛實現的功能是群發消息,下面看下私聊是如何實現的。點對點通信需要配置多個用戶,我們用 SpringSecurity 添加兩個用戶。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
//添加兩個用戶 admin,sang,密碼設為123。
.withUser("admin")
.password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
.roles("admin")
.and()
.withUser("sang")
.password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
.roles("user");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
@Configuration
@EnableWebSocketMessageBroker //通過此注解開啟 WebSocket 消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
//客戶端接收服務端消息的地址前綴
//在群發的基礎上,添加一個客戶端接收地址的前綴。
config.enableSimpleBroker("/topic","/queue");
//客戶端給服務端發消息的地址前綴
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//定義一個前綴為 "chat" 的endpoint,并開啟 sockJs支持。
// sockJs 可以解決對 WebSocket 的兼容性問題,客戶端將通過這里配置的 url 建立 WebSocket 連接
registry.addEndpoint("/chat").withSockJS();
}
}
@Controller
public class GreetingController {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
//群發消息使用 @SendTo 注解
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Message greeting(Message message) throws Exception{
return message;
}
//點對點發送消息使用 SimpMessagingTemplate 實現
@MessageMapping("/chat") //來自 "/app/chat" 的消息將會被此方法處理
public void chat(Principal principal, Chat chat)throws Exception{
String from = principal.getName();
chat.setFrom(from);
simpMessagingTemplate.convertAndSendToUser(chat.getTo(),"/queue/chat",chat);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>群聊</title>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="/chat.js"></script>
</head>
<body>
<div>
<div id="chatsContent"></div>
<div>
請輸入聊天內容:<input type="text" id="content" placeholder="聊天內容">
目標用戶:<input type="text" id="to" placeholder="目標用戶">
<button type="button" id="send">發送</button>
</div>
</div>
</body>
</html>
var stompClient = null;
//建立一個 WebSocket 連接,建立連接之前必須輸入用戶名
function connect() {
//創建一個 SockeJS 實例
var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
//使用 subscribe 方法訂閱服務端發送回來的消息,并將服務端發送的消息展示出來
stompClient.subscribe('/user/queue/chat', function (chat) {
showGreeting(JSON.parse(chat.body));
})
})
}
//發送信息
function sendMsg() {
stompClient.send("/app/chat", {},
JSON.stringify({'content': $('#content').val(), 'to': $('#to').val()}));
}
//展示信息
function showGreeting(message) {
$('#chatsContent')
.append("<div>" + message.from + ":" + message.content + "</div>")
}
$(function () {
connect();
$('#send').click(function () {
sendMsg();
});
})
演示效果時請使用不同用戶登錄的同一瀏覽器或者不同瀏覽器演示
關于使用SpringBoot和WebSocket實現簡易聊天室的代碼分享就到這了,詳細使用情況還需要大家自己使用過才領會。如果想了解更多相關內容,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。