从零开始手写mmo游戏从框架到爆炸(六)— 消息处理工厂

2024-02-07 14:04

本文主要是介绍从零开始手写mmo游戏从框架到爆炸(六)— 消息处理工厂,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        就好像门牌号一样,我们需要把消息路由到对应的楼栋和楼层,总不能像菜鸟一样让大家都来自己找数据吧。

        首先这里我们参考了rabbitmq中的topic与tag模型,topic对应类,tag对应方法。

新增一个模块,专门记录路由eternity-command

ServerTag.java

public interface ServerTag {/**** 打招呼*/int TAG_HELLO_HI = 1;}

ServerTopic.java

public interface ServerTopic {/**** 问候*/int TOPIC_HELLO = 1;}

然后再core中引入这个模块,同时增加反射依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.reflections</groupId><artifactId>reflections</artifactId><version>0.9.10</version></dependency><dependency><groupId>com.loveprogrammer</groupId><artifactId>eternity-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.loveprogrammer</groupId><artifactId>eternity-command</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

在core中增加一个文件夹

创建两个注解:

TagListener

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.METHOD;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TagListener {/*** 订阅的tag*/int tag() default 0;/*** 请求方消息类型*/Class<?> messageClass() default Object.class;}

TopicListener

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TopicListener {/*** 订阅的主题*/int topic() default 0;
}

接口IHandler

public interface IHandler {}

抽象实现类BaseHandler

public abstract class BaseHandler implements IHandler{}

hello实现类


import com.loveprogrammer.base.network.command.BaseHandler;
import com.loveprogrammer.base.network.command.HandlerFactory;
import com.loveprogrammer.base.network.command.anotation.TagListener;
import com.loveprogrammer.base.network.command.anotation.TopicListener;
import com.loveprogrammer.command.server.ServerTag;
import com.loveprogrammer.command.server.ServerTopic;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;/*** @ClassName HelloHandler* @Description 测试handler* @Author admin* @Date 2024/2/5 15:49* @Version 1.0*/
@Component
@TopicListener(topic = ServerTopic.TOPIC_HELLO)
public class HelloHandler extends BaseHandler {public static final Logger log = LoggerFactory.getLogger(HelloHandler.class);@TagListener(tag = ServerTag.TAG_HELLO_HI,messageClass = String.class)public void sayHi(Channel channel, String msg){log.info("say hi");}
}

创建监听器工厂 HandlerFactory


import com.loveprogrammer.base.network.command.anotation.TopicListener;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** @ClassName HandlerFactory* @Description 监听器工厂* @Author admin* @Date 2024/2/5 11:21* @Version 1.0*/
@Component
public class HandlerFactory implements CommandLineRunner {public static final Logger log = LoggerFactory.getLogger(HandlerFactory.class);public Map<Integer, Class> handlerMap = new HashMap<>();@Overridepublic void run(String... args) throws Exception {// 找到所有实现类Reflections reflections = new Reflections("com.loveprogrammer.base.network.command.handler");// 获取在指定包扫描的目录所有的实现类Set<Class<? extends BaseHandler>> classes = reflections.getSubTypesOf(BaseHandler.class);for (Class<? extends IHandler > aClass : classes) {try {TopicListener listeners = aClass.getAnnotation(TopicListener.class);Integer topic = listeners.topic();handlerMap.put(topic, aClass);log.info("初始化消息监听器成功 {}",aClass.getName());} catch (Exception e) {log.error("初始化" + aClass.getName() + "消息监听器失败",e);}}}
}

启动server,查看监听器是否初始化成功。

2024-02-05 16:09:33.860  INFO 14144 --- [           main] c.l.base.network.command.HandlerFactory  : 初始化消息监听器成功 com.loveprogrammer.base.network.command.handler.HelloHandler
(♥◠‿◠)ノ゙  springboot启动成功   ლ(´ڡ`ლ)゙ 

上一篇:从零开始手写mmo游戏从框架到爆炸(五)— 集成springboot-CSDN博客

全部源码详见:

gitee : eternity-online: 多人在线mmo游戏 - Gitee.com

分支:step-06

这篇关于从零开始手写mmo游戏从框架到爆炸(六)— 消息处理工厂的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687958

相关文章

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Python处理超大规模数据的4大方法详解

《Python处理超大规模数据的4大方法详解》在数据的奇妙世界里,数据量就像滚雪球一样,越变越大,从最初的GB级别的小数据堆,逐渐演变成TB级别的数据大山,所以本文我们就来看看Python处理... 目录1. Mars:数据处理界的 “变形金刚”2. Dask:分布式计算的 “指挥家”3. CuPy:GPU

Python中CSV文件处理全攻略

《Python中CSV文件处理全攻略》在数据处理和存储领域,CSV格式凭借其简单高效的特性,成为了电子表格和数据库中常用的文件格式,Python的csv模块为操作CSV文件提供了强大的支持,本文将深入... 目录一、CSV 格式简介二、csv模块核心内容(一)模块函数(二)模块类(三)模块常量(四)模块异常

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

Spring Boot Controller处理HTTP请求体的方法

《SpringBootController处理HTTP请求体的方法》SpringBoot提供了强大的机制来处理不同Content-Type​的HTTP请求体,这主要依赖于HttpMessageCo... 目录一、核心机制:HttpMessageConverter​二、按Content-Type​处理详解1.

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B