从零开始实现放置游戏(十三)——实现战斗挂机(4)添加websocket组件

霍财
2023-12-01

前两张,我们已经实现了登陆界面和游戏的主界面。不过游戏主界面的数据都是在前端写死的文本,本章我们给game模块添加websocket组件,实现前后端通信,这样,前端的数据就可以从后端动态获取到了。

一、添加maven依赖
  在game模块的pom中,我们添加3个依赖包如下:

复制代码
1
2
3 org.springframework
4 spring-websocket
5 5.1.6.RELEASE
6
7
8 org.springframework
9 spring-messaging
10 5.1.6.RELEASE
11
12
13 javax.websocket
14 javax.websocket-api
15 1.1
16 provided
17
复制代码
二、后端添加MessageHub
  在com.idlewow.game.hub下MessageHub,这个类将主要负责接收客户端的websocket信息。代码如下:

MessageHub
  Hub类主要包括OnOpen、OnMessage、OnClose、OnError 4个方法。

在OnOpen建立连接时,我们从HttpSession中获取角色Id,并加载角色信息,更新在线数据等。这里我们创建一个GameWorld类,将在线列表等游戏世界的全局静态数据保存在其中。

在OnMessage方法接收到客户端数据时,我们将消息在MessageHandler中统一处理。

OnClose和OnError对应关闭连接和异常发生事件,关闭连接时,需要将游戏角色从在线列表中清除。发生异常时,我们暂时仅记录日志。

注意:在MesssageHub的注解中,我们给其配置了一个HttpSessionConfigurator。是为了在socket消息中获取到HttpSession数据。如果不加这个配置,HttpSession是获取不到的。其代码如下:

复制代码
1 public class HttpSessionConfigurator extends SpringConfigurator {
2 @Override
3 public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
4 HttpSession httpSession = (HttpSession) request.getHttpSession();
5 sec.getUserProperties().put(HttpSession.class.getSimpleName(), httpSession);
6 super.modifyHandshake(sec, request, response);
7 }
8 }
复制代码
三、定义消息类型
  在socket通信时,我们必须定义消息的数据结构,并准备相应文档,方便前后端通信。

这里我们创建消息类WowMessage,并规定其由header和content两部分构成。header中主要包括消息类型,请求时间等通用参数。content主要包括具体的业务数据。

整个消息类的UML图如下,其中例举了4种具体的消息类型,LoadCache缓存加载,Login登陆消息,Chat聊天消息,Move地图移动消息。

四、后端消息处理

在定义好消息类型后,我们即可在后端对相应的消息进行处理。代码如下:

在handleMessage方法中,我们根据header中传入的messageCode,来确定是何种消息,并转入对应的处理子方法。

比如处理地图移动的handleMoveMessage方法,在这个方法中,我们将人物信息缓存数据中的当前地图ID修改为移动后的地图ID,从原地图在线列表中移除此角色,在目标地图在线列表中添加此角色。并返回目标地图的信息给前端以便展示。

MessageHandler
五、前端socket处理
  对应后端的MessageHub,前端也需要一个socket客户端,这里我们创建一个WowClient对象,负责最外层的消息处理逻辑。

复制代码
1 const WowClient = function () {
2 this.cache = {
3 version: 0,
4 levelExpMap: []
5 };
6 this.cacheKey = “idlewow_client_cache”;
7 this.hubUrl = “ws://localhost:20010/hub”;
8 this.webSocket = new WebSocket(this.hubUrl);
9 this.webSocket.onopen = function (event) {
10 console.log(‘WebSocket建立连接’);
11 wowClient.sendLogin();
12 wowClient.loadCache();
13 };
14 this.webSocket.onmessage = function (event) {
15 console.log(‘WebSocket收到消息:%c’ + event.data, ‘color:green’);
16 var message = JSON.parse(event.data) || {};
17 console.log(message);
18 wowClient.receive(message);
19 };
20 this.webSocket.onclose = function (event) {
21 console.log(‘WebSocket关闭连接’);
22 };
23 this.webSocket.onerror = function (event) {
24 console.log(‘WebSocket发生异常’);
25 };
26 };
复制代码
  另外,前端同样也需要定义消息类型,

复制代码
1 const RequestMessage = function () {
2 this.header = {
3 messageCode: “”,
4 requestTime: new Date(),
5 version: “1.0”
6 };
7 this.content = {};
8 };
9
10 const MessageCode = {
11 // 预处理
12 LoadCache: “0010”,
13 // 系统命令
14 Login: “1001”,
15 RefreshOnline: “1002”,
16 // 玩家命令
17 Chat: “2001”,
18 Move: “2002”,
19 BattleMob: “2100”
20 };
复制代码
  具体的消息处理逻辑和消息实体的创建,通过原型方法生成。完整的js文件如下:

main.js

小结
  本章主要实现的socket的通信逻辑,对消息的处理涉及了手机游戏的业务处理逻辑,仅简单的讲了一些。

另外因为时隔较长,代码裁剪工作量较大。本章仅对已完成的代码做了粗略裁剪。源代码的一些变动,文中将讲解一些主要的,其他的就不再赘述了。

对一些边角的内容,代码会变化,但文中未体现的,如有问题,可留言咨询。
  详细:http://nbcjzx.com/

 类似资料: