實現功能:遊戲管理裏發佈遊戲公告,其它遊戲玩家頁面可以立刻接受到遊戲公告信息。css
下面直接上代碼案例,這裏主要展現關鍵代碼,底部有源碼。html
主要是添加springBoot和webSocket相關jar包,和一些輔助工具jar包(注意我採用的是springBoot2.1.0版本java
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jincou.websocket</groupId> <artifactId>websocketstudy</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>websocketstudy</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.BUILD-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--springboot和websocket整合包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!--輔助包--> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> <version>0.32-1</version> </dependency> <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.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
這個是websocket配置中心,配置一些核心配置。jquery
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 //註解用於開啓使用STOMP協議來傳輸基於代理(MessageBroker)的消息,這時候控制器(controller)開始支持@MessageMapping,就像是使用@requestMapping同樣。 @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { /** * 註冊端點,發佈或者訂閱消息的時候須要鏈接此端點 * setAllowedOrigins 非必須,*表示容許其餘域進行鏈接 * withSockJS 表示開始sockejs支持 */ public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/endpoint-websocket").setAllowedOrigins("*").withSockJS(); } /** * 配置消息代理(中介) * enableSimpleBroker 服務端推送給客戶端的路徑前綴 * setApplicationDestinationPrefixes 客戶端發送數據給服務器端的一個前綴 */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } }
管理員發佈公告消息對應的接口git
/* *模擬遊戲公告 */ @Controller public class GameInfoController { //@MessageMapping和@RequestMapping功能相似,用於設置URL映射地址,瀏覽器向服務器發起請求,須要經過該地址。 //若是服務器接受到了消息,就會對訂閱了@SendTo括號中的地址傳送消息。 @MessageMapping("/gonggao/chat") @SendTo("/topic/game_chat") public OutMessage gameInfo(InMessage message){ return new OutMessage(message.getContent()); } }
admin頁面和user頁面惟一的區別就是管理員多一個發送公告的權限,其它都同樣,user1和user2徹底同樣。github
(1)admin.htmlweb
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <head> <title>Hello WebSocket</title> <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="/gonggao/main.css" rel="stylesheet"> <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="/gonggao/app.js"></script> </head> <body> <noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!</h2></noscript> <div id="main-content" class="container"> <div class="row"> <div class="col-md-6"> <form class="form-inline"> <div class="form-group"> <label for="connect">創建鏈接通道:</label> <button id="connect" class="btn btn-default" type="submit">Connect</button> <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect </button> </div> </form> </div> <div class="col-md-6"> <form class="form-inline"> <div class="form-group"> <label for="name">發佈新公告</label> <input type="text" id="content" class="form-control" placeholder="請輸入..."> </div> <button id="send" class="btn btn-default" type="submit">發佈</button> </form> </div> </div> <div class="row"> <div class="col-md-12"> <table id="conversation" class="table table-striped"> <thead> <tr> <th>遊戲公告內容</th> </tr> </thead> <tbody id="notice"> </tbody> </table> </div> </div> </div> </body> </html>
(2)user1.htmlspring
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <head> <title>Hello WebSocket</title> <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="/gonggao/main.css" rel="stylesheet"> <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="/gonggao/app.js"></script> </head> <body> <noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!</h2></noscript> <div id="main-content" class="container"> <div class="row"> <div class="col-md-6"> <form class="form-inline"> <div class="form-group"> <label for="connect">創建鏈接通道:</label> <button id="connect" class="btn btn-default" type="submit">Connect</button> <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect </button> </div> </form> </div> </div> <div class="row"> <div class="col-md-12"> <table id="conversation" class="table table-striped"> <thead> <tr> <th>遊戲公告內容</th> </tr> </thead> <tbody id="notice"> </tbody> </table> </div> </div> </div> </body> </html>
(3)user2.htmlapache
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <head> <title>Hello WebSocket</title> <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="/gonggao/main.css" rel="stylesheet"> <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="/gonggao/app.js"></script> </head> <body> <noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!</h2></noscript> <div id="main-content" class="container"> <div class="row"> <div class="col-md-6"> <form class="form-inline"> <div class="form-group"> <label for="connect">創建鏈接通道:</label> <button id="connect" class="btn btn-default" type="submit">Connect</button> <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect </button> </div> </form> </div> </div> <div class="row"> <div class="col-md-12"> <table id="conversation" class="table table-striped"> <thead> <tr> <th>遊戲公告內容</th> </tr> </thead> <tbody id="notice"> </tbody> </table> </div> </div> </div> </body> </html>
這個是客戶端鏈接websocket的核心,經過html的點擊事件來完成。bootstrap
var stompClient = null; //這個方法僅僅是用來改變樣式,不是核心 function setConnected(connected) { $("#connect").prop("disabled", connected); $("#disconnect").prop("disabled", !connected); if (connected) { $("#conversation").show(); } else { $("#conversation").hide(); } $("#notice").html(""); } //一、創建鏈接(先鏈接服務端配置文件中的基站,創建鏈接,而後訂閱服務器目錄消息 function connect() { //一、鏈接SockJS的endpoint是「endpoint-websocket」,與後臺代碼中註冊的endpoint要同樣。 var socket = new SockJS('/endpoint-websocket'); //二、用stom進行包裝,規範協議 stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { //三、創建通信 setConnected(true); console.log('Connected: ' + frame); //四、經過stompClient.subscribe()訂閱服務器的目標是'/topic/game_chat'發送過來的地址,與@SendTo中的地址對應。 stompClient.subscribe('/topic/game_chat', function (result) { console.info(result) showContent(JSON.parse(result.body)); }); }); } //二、關閉鏈接 function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } //三、遊戲管理員發送公告信息(這個也是遊戲用戶所沒有功能,其它都同樣) function sendName() { //一、經過stompClient.send 向/app/gonggao/chat 目標 發送消息,這個是在控制器的@messageMapping 中定義的。(/app爲前綴,配置裏配置) stompClient.send("/app/gonggao/chat", {}, JSON.stringify({'content': $("#content").val()})); } //四、訂閱的消息顯示在客戶端指定位置 function showContent(body) { $("#notice").append("<tr><td>" + body.content + "</td> <td>"+new Date(body.time).toLocaleString()+"</td></tr>"); } $(function () { $("form").on('submit', function (e) { e.preventDefault(); }); $( "#connect" ).click(function() { connect(); }); $( "#disconnect" ).click(function() { disconnect(); }); $( "#send" ).click(function() { sendName(); }); });
首先很明顯看的出,websocket最大的優勢,就是能夠服務端主動向客戶端發送消息,而此前http只能是客戶端向服務端發送請求。
gitHub源碼:https://github.com/yudiandemingzi/spring-boot-websocket-study
想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中校【19】