实现游戏公告功能

实现功能:游戏管理里发布游戏公告,其它游戏玩家页面能够马上接受到游戏公告信息。

下面直接上代码案例,这里主要展示关键代码,底部有源码。

一、案例

1、pom.xml文件

主要是添加springBoot和webSocket相关jar包,和一些辅助工具jar包(注意我采用的是springBoot2.1.0版本

<?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>

pom.xml

2、WebSocketConfig

这个是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
//注解用于开启使用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"); }
}

3、GameInfoController

管理员发布公告消息对应的接口

/*
*模拟游戏公告
*/
@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());
}
}

4、管理员页面和用户页面

admin页面和user页面唯一的区别就是管理员多一个发送公告的权限,其它都一样,user1和user2完全一样。

(1)admin.html

<!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>

admin.html

(2)user1.html

<!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>

user1.html

 (3)user2.html

<!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>

user2.html

5.app.js

这个是客户端连接websocket的核心,通过html的点击事件来完成。

var stompClient = null;

//这个方法仅仅是用来改变样式,不是核心
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#notice").html("");
} //1、建立连接(先连接服务端配置文件中的基站,建立连接,然后订阅服务器目录消息
function connect() {
//1、连接SockJS的endpoint是“endpoint-websocket”,与后台代码中注册的endpoint要一样。
var socket = new SockJS('/endpoint-websocket'); //2、用stom进行包装,规范协议
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) { //3、建立通讯
setConnected(true);
console.log('Connected: ' + frame); //4、通过stompClient.subscribe()订阅服务器的目标是'/topic/game_chat'发送过来的地址,与@SendTo中的地址对应。
stompClient.subscribe('/topic/game_chat', function (result) {
console.info(result)
showContent(JSON.parse(result.body));
});
});
} //2、关闭连接
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
} //3、游戏管理员发送公告信息(这个也是游戏用户所没有功能,其它都一样)
function sendName() {
//1、通过stompClient.send 向/app/gonggao/chat 目标 发送消息,这个是在控制器的@messageMapping 中定义的。(/app为前缀,配置里配置)
stompClient.send("/app/gonggao/chat", {}, JSON.stringify({'content': $("#content").val()}));
} //4、订阅的消息显示在客户端指定位置
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(); });
});

6、查看运行结果

7、小总结

首先很明显看的出,websocket最大的优点,就是可以服务端主动向客户端发送消息,而此前http只能是客户端向服务端发送请求。

gitHub源码:https://github.com/yudiandemingzi/spring-boot-websocket-study

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。中校【19】

 

WebSocket(2)---实现游戏公告功能的更多相关文章

  1. WebSocket(3)---实现一对一聊天功能

    实现一对一聊天功能 功能介绍:实现A和B单独聊天功能,即A发消息给B只能B接收,同样B向A发消息只能A接收. 本篇博客是在上一遍基础上搭建,上一篇博客地址:[WebSocket]---实现游戏公告功能 ...

  2. ado.net实现一个通知公告功能

    一.建立相应的数据库,此处就不多说了,相信大家都非常了解

  3. html5利用websocket完成的推送功能(tomcat)

    html5利用websocket完成的推送功能(tomcat) 利用websocket和java完成的消息推送功能,服务器用的是tomcat7.0.42,一些东西是自己琢磨的,也不知道恰不恰当,不恰当 ...

  4. 【cocos2d-x制作别踩白块儿】第九期:游戏计时功能(附源代码)

    游戏没有计时,不是坑爹吗? 这一期,我们将来加入游戏计时功能. 1. 定义变量和函数 我们先在HelloWorldScene.h中定义几个变量和函数 long startTime; bool time ...

  5. Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币

    什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...

  6. 第18章-使用WebSocket和STOMP实现消息功能

    Spring 4.0为WebSocket通信提供了支持,包括: 发送和接收消息的低层级API: 发送和接收消息的高级API: 用来发送消息的模板: 支持SockJS,用来解决浏览器端.服务器以及代理不 ...

  7. Unity3D 游戏计时功能实现

    最近工作实在是太忙了,没办法认真写博客,但是还是要好好记录下日常的学习. 需求 各类游戏中都大量运用到计时功能,不管是直接显示的在前端UI,还是后台运行. 思路 Unity中提供了Time类可以方便的 ...

  8. 实例源码--IOS高仿微信打飞机游戏(完整功能)

    下载源码 技术要点: 1. IOS游戏开发基础框架 2. 高仿打飞机游戏 3. 游戏背景音频技术 4.源码详细的中文注释 ……. 详细介绍: 1. IOS游戏开发基础框架 此套源码为涉及IOS游戏开发 ...

  9. html5利用websocket完成的推送功能

    利用websocket和java完成的消息推送功能,服务器用的是tomcat7.0,一些东西是自己琢磨的,也不知道恰不恰当,不恰当处,还请各位见谅,并指出. 程序简单来说,就是客户A可以发送消息给客户 ...

随机推荐

  1. Linux从入门到进阶全集——【第十四集:Shell基础命令】

    1,Shell就是命令行执行器 2,作用:将外层引用程序的例如ls ll等命令进行解释成01表示的二进制代码给内核,从而让硬件执行:硬件的执行结果返回给shell,shell解释成我们能看得懂的代码返 ...

  2. Scrapy:Python实现scrapy框架爬虫两个网址下载网页内容信息——Jason niu

    import scrapy class DmozSpider(scrapy.Spider): name ="dmoz" allowed_domains = ["dmoz. ...

  3. HDU 6437 Problem L.Videos (最大费用)【费用流】

    <题目链接> 题目大意: 一天有N个小时,有m个节目(每种节目都有类型),有k个人,连续看相同类型的节目会扣w快乐值.每一种节目有都一个播放区间[l,r].每个人同一时间只能看一个节目,看 ...

  4. 2013年省赛I题 Thrall’s Dream

    2013年省赛I题判断单向联通,用bfs剪枝:从小到大跑,如果遇到之前跑过的点(也就是编号小于当前点的点),就o(n)传递关系. bfs #include<iostream> #inclu ...

  5. 通过javap终极理解++i和i++的区别

    一直在学习Java,碰到了很多问题,碰到了很多关于i++和++i的难题,以及最经典的String str = "abc" 共创建了几个对象的疑难杂症. 知道有一日知道了java的反 ...

  6. Python的使用方法

    1 安装turtle Python2安装命令: pip install turtule Python3安装命令: pip3 install turtle 因为turtle库主要是在Python2中使用 ...

  7. Android Getting Started

    Building Your First App Creating an Android Project 介绍如何Android开发环境,具体是:怎么使用Eclipse工具 Create a Proje ...

  8. mysql5.7.X版本only_full_group_by问题解决

    一.出错原因 最近因为开发数据库与部署数据库版本不同,带来了几个问题,其中only_full_group_by问题是之前没有遇到的. 具体报错如下 [Err] 1055 - Expression #1 ...

  9. mysql的复习

    . 着重号,区分字段和关键字的符号 +号是运算的 起别名,其中的as可以省略 ifnull(expr1,expr2),expr1代表输入的字段,expr2代表如果输入的字段是null则为expr2 条 ...

  10. hadoop2-elasticsearch的安装

    本文主要讲elasticsearch-2.2.1的安装过程. 准备工作: 1.搭建虚拟机 你需要先参考 hadoop2集群环境搭建 把你的虚拟机搭建起来-hadoop环境可以先不用搭建(完成步骤1到步 ...