Java SpringBoot下的WebSocket
前面我們已經(jīng)講了如何搭建一個(gè)SpringBoot的Web框架,那么搭完了框架總要搞點(diǎn)事情吧具温,今天咱們就來做一個(gè)基于SpringBoot的簡易聊天室掠拳。
聊天
WebSocket簡介
工欲善其事必先利其器癞揉,我們先來講一下什么是WebScoket。WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議溺欧。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動(dòng)發(fā)送信息給客戶端喊熟。,也就是說我們可以利用瀏覽器給服務(wù)器發(fā)送消息姐刁,服務(wù)器也可以給瀏覽器發(fā)送消息芥牌,目前的主流瀏覽器對WebSocket的支持都還不錯(cuò),但是在實(shí)際開發(fā)中使用WebSocket工作量會很大聂使,并且還有對瀏覽器的兼容問題壁拉,所以這個(gè)時(shí)候我們更多的是使用WebSocket的一個(gè)子協(xié)議stomp拐叉,利用它來快速實(shí)現(xiàn)我們的功能。
環(huán)境
我們做的建議公共聊天室需要在SpringBoot的POM文件中添加兩個(gè)依賴扇商,不知道怎么搭建SpringBoot的朋友可以看下我前面發(fā)的SpringBoot搭建的方法。
需要的maven依賴:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
開始擼代碼
搭建完了基本的開發(fā)環(huán)境之后我們來寫代碼宿礁,首先我們先寫一個(gè)關(guān)于WebSocket的節(jié)點(diǎn)以及模式的配置類案铺,代碼里有詳細(xì)的注解。
package com.guanglan.config; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; /** * Created by GuangLan on 2017/12/21. */ @Configuration //配置注解 @EnableWebSocketMessageBroker //@EnableWebSocketMessageBroker注解表示開啟使用STOMP協(xié)議來傳輸基于代理的消息梆靖,Broker就是代理的意思控汉。 public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { /** * configureMessageBroker用來配置消息代理模式,我們做的是公共聊天室所以用topic即可 * @param config */ @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); } /** * registerStompEndpoints方法表示注冊STOMP協(xié)議的節(jié)點(diǎn)返吻,并指定映射的URL的位置 * @param stompEndpointRegistry */ @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { //stompEndpointRegistry.addEndpoint("/MyWebsocket").withSockJS(); // 的意思就是注冊STOMP協(xié)議節(jié)點(diǎn)姑子,并且使用SockJS協(xié)議。 stompEndpointRegistry.addEndpoint("MyWebsocket").withSockJS(); } }
接下來我們要建立兩個(gè)實(shí)體類测僵,一個(gè)是接收客戶端發(fā)來的消息類街佑,一個(gè)是返回消息的類。
返回消息類:
package com.guanglan.entry; /** * 返回消息類 * Created by GuangLan on 2017/12/21. */ public class ResponseMessage { private String name; //消息發(fā)送者 private String message; //消息內(nèi)容 private String dateTime; //發(fā)送時(shí)間 public ResponseMessage(String name, String message,String dateTime){ this.name = name; this.message = message; this.dateTime = dateTime; } public String getResponseMessage(){ return "發(fā)送時(shí)間 : "+dateTime+"\n"+name+" : "+message+" "; } }
接收消息類:
package com.guanglan.entry; /** * 接收消息類 * Created by GuangLan on 2017/12/21. */ public class RequestMessage { private String name; //消息發(fā)送者 private String message; //消息內(nèi)容 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
接下來捍靠,我們建立接收消息和發(fā)送消息的控制類:
package com.guanglan.controller; import com.guanglan.entry.RequestMessage; import com.guanglan.entry.ResponseMessage; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * Created by GuangLan on 2017/12/21. */ @Controller public class WebSocketController { @MessageMapping("/guanglan") //客戶端請求的地址 @SendTo("/topic/getResponse") //返回給客戶端消息的地址 public ResponseMessage responseMessage(RequestMessage message) { //獲取當(dāng)前時(shí)間 LocalDateTime localDateTime = LocalDateTime.now(); DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); //將從服務(wù)端接受的信息返回到頁面上 return new ResponseMessage(message.getName(),message.getMessage(),localDateTime.format(format)); } }
這樣主體流程就差不多了沐旨,我們在templates中建立一個(gè)名字為websocket的html5文件,并寫入以下內(nèi)容:
<html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>公共聊天室WebSocket</title> <link rel="stylesheet"/> <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> </head> <body onload="disconnect()"> <noscript><h2 style="color: #e80b0a;">Sorry榨婆,瀏覽器不支持WebSocket</h2></noscript> <div> <div> <button id="connect" onclick="connect();" class="btn btn-success" style="width: 200px;height:60px;">連接</button> <button id="disconnect" disabled="disabled" onclick="disconnect();" class="btn btn-danger" style="width: 200px;height:60px;">斷開</button> </div> <div id="conversationDiv"> <div class="form-group"> <label for="name">姓名</label> <input type="text" id="name" class="form-control" placeholder="輸入你的名字" style="width: 500px;"/> </div> <div class="form-group"> <textarea id="message" class="form-control" rows="3" style="width: 500px;"> </textarea> </div> <button type="button" class="btn btn-info" id="sendName" onclick="sendName();">發(fā)送</button> <br/> <div class="form-group"> <p id="response"></p> </div> </div> </div> <script type="text/javascript"> var stompClient = null; function setConnected(connected) { document.getElementById("connect").disabled = connected; document.getElementById("disconnect").disabled = !connected; document.getElementById("conversationDiv").style.visibility = connected ? 'visible' : 'hidden'; $("#response").html(); } function connect() { var socket = new SockJS('/MyWebsocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); stompClient.subscribe('/topic/getResponse', function (response) { showResponse(JSON.parse(response.body).responseMessage); }) }); } function disconnect() { if (stompClient != null) { stompClient.disconnect(); } setConnected(false); } function sendName() { var name = $('#name').val(); var message = $('#message').val(); stompClient.send("/guanglan", {}, JSON.stringify({'name': name,'message':message})); } function showResponse(message) { $("#response").append("<br/>"+message); } </script> </body> </html>
馬上就要大功告成了磁携,不要?dú)怵H哦,我們在建立一個(gè)映射HTML5文件的類就OK了:
package com.guanglan.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * Created by GuangLan on 2017/12/21. */ @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { //訪問路徑以及頁面文件的名字 registry.addViewController("/websocket").setViewName("/websocket"); } }
這樣一個(gè)簡易的WebSocket聊天室就完成了良风。
主頁面
如果您按照上述地址訪問后出現(xiàn)上面的頁面那么恭喜您搭建成功了谊迄!
下面看看效果吧
效果圖
點(diǎn)擊鏈接后會出現(xiàn)聊天室的頁面,我在瀏覽器上建立了三個(gè)連接烟央,分別發(fā)送了消息统诺,效果如上。
好了吊档,今天的基于SpringBoot的簡易公共聊天室就講到這里篙议,如果您喜歡小編的作品請關(guān)注哦!