从零开始手写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游戏从框架到爆炸(六)— 消息处理工厂
就好像门牌号一样,我们需要把消息路由到对应的楼栋和楼层,总不能像菜鸟一样让大家都来自己找数据吧。 首先这里我们参考了rabbitmq中的topic与tag模型,topic对应类,tag对应方法。 新增一个模块,专门记录路由eternity-…...
Go基础学习笔记-知识点
学习笔记记录了我在学习官方文档过程中记的要点,可以参考学习。 go build *.go 文件 编译 go run *.go 执行 go mod init 生成依赖管理文件 gofmt -w *.go 格式换名称的大小写用来控制方法的可见域主方法及包命名规范 package main //注意package的命名࿰…...
jvm几个常见面试题整理
1. Full GC触发机制有如下5种情况。 (1)调用System.gc()时,系统建议执行Full GC,但是不必然执行。(2)老年代空间不足。(3)方法区空间不足。(4)老年代的最大可用连续空间小于历次晋升到老年代对象的平均大小就会进行Full GC。(5)由Eden区、S0(From)区向S…...
ReentrantLock 和 公平锁
ReentrantLock 和 公平锁 一、基本介绍 ReentrantLock(重入锁) 是一个独占式锁,具有和synchronize的监视器锁基本相同的行为和语意。但和synchronized相比,它更加的灵活、强大、增加了轮询、超时、中断等高级功能以及可以创建公平和非公平锁。Reentran…...
使用Postman做API自动化测试
Postman最基本的功能用来重放请求,并且配合良好的response格式化工具。 高级点的用法可以使用Postman生成各个语言的脚本,还可以抓包,认证,传输文件。 仅仅做到这些还不能够满足一个系统的开发,或者说过于琐碎&#…...
入门指南|Chat GPT 的兴起:它如何改变数字营销格局?
随着数字营销的不断发展,支持数字营销的技术也在不断发展。OpenAI 的 ChatGPT 是一项备受关注的突破性工具。凭借其先进的自然语言处理能力,ChatGPT 已被证明是全球营销人员的宝贵资产。在这份入门指南中,我们将探讨Chat GPT对数字营销专家及…...
【C#】.net core 6.0 创建默认Web应用,以及默认结构讲解,适合初学者
欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。…...
Linux中的numactl命令指南
假设我们想控制线程如何被分配到处理器核心,或者选择我们想分配数据的位置,那么numactl命令就适合此类任务。在这篇文章中,我们讨论了如何使用numactl命令执行此类操作。 目录: 介绍语法命令总结参考文献 简介 现代处理器采用…...
AD域国产替代方案,助力某金融企业麒麟信创电脑实现“真替真用”
近期收到不少企业客户反馈采购的信创PC电脑用不起来,影响信创改造的进度。例如,某金融企业积极响应国产化信创替代战略,购置了一批麒麟操作系统电脑。分发使用中发现了如下问题: • 当前麒麟操作系统电脑无法做到统一身份认证&…...
抽象springBoot报错
Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译:无法配置DataSource:未指定“url”属性,并且无法配置嵌入数据源。 DataSource 翻译:数据源 得…...
Linux的打包压缩与解压缩---tar、xz、zip、unzip
最近突然用到了许久不用的压缩解压缩命令,真的陌生, 哈哈,记录一下,后续就不用搜索了。 tar的打包 tar -cvf 压缩有的文件名称 需要压缩的文件或文件夹tar -cvf virtualbox.tar virtualbox/ tar -zcvf virtualbox.tar virtualbo…...
在angular12中proxy.conf.json中配置详解
一、proxy.conf.json文件的目录 二、proxy.conf.json文件中的配置 "/xxx/api": {"target": "地址/api","secure": false,"logLevel": "debug","changeOrigin": true,"pathRewrite": {"…...
PyTorch 中音频信号处理库torchaudio的详细介绍
torchaudio 是 PyTorch 深度学习框架的一部分,是 PyTorch 中处理音频信号的库,专门用于处理和分析音频数据。它提供了丰富的音频信号处理工具、特征提取功能以及与深度学习模型结合的接口,使得在 PyTorch 中进行音频相关的机器学习和深度学习…...
OpenAI研究揭示:ChatGPT对生物武器制造影响有限
### OpenAI研究揭示:ChatGPT对生物武器制造影响有限 在最近的一项引人注目的研究中,OpenAI探索了其旗舰人工智能产品GPT-4在辅助制造生物武器方面的潜力。尽管公众对人工智能可能带来的潜在风险表示担忧,但OpenAI的发现却意味着这种担忧可能…...
IntelliJ IDEA 2023.3发布,AI 助手出世,新特性杀麻了!!
目录 关键亮点 对 Java 21 功能的完全支持 调试器中的 Run to Cursor(运行到光标)嵌入选项 带有编辑操作的浮动工具栏 用户体验优化 Default(默认)工具窗口布局选项 默认颜色编码编辑器标签页 适用于 macOS 的新产品图标 Speed Sear…...
async 与 await(JavaScript)
目录捏 前言一、async二、await三、使用方法总结 前言 async / await 是 ES2017(ES8) 提出的基于 Promise 解决异步的最终方案。上一篇文章介绍了 回调地狱 与 Promise(JavaScript),因为 Promise 的编程模型依然充斥着大量的 then 方法&#…...
GPT-1, GPT-2, GPT-3, GPT-3.5, GPT-4论文内容解读
目录 1 ChatGPT概述1.1 what is chatGPT1.2 How does ChatGPT work1.3 The applications of ChatGPT1.3 The limitations of ChatGPT 2 算法原理2.1 GPT-12.1.1 Unsupervised pre-training2.1.2 Supervised fine-tuning2.1.3 语料2.1.4 分析 2.2 GPT-22.3 GPT-32.4 InstructGPT…...
第62讲商品搜索动态实现以及性能优化
商品搜索后端动态获取数据 后端动态获取数据: /*** 商品搜索* param q* return*/GetMapping("/search")public R search(String q){List<Product> productList productService.list(new QueryWrapper<Product>().like("name", q)…...
我的PyTorch模型比内存还大,怎么训练呀?
原文:我的PyTorch模型比内存还大,怎么训练呀? - 知乎 看了一篇比较老(21年4月文章)的不大可能训练优化方案,保存起来以后研究一下。 随着深度学习的飞速发展,模型越来越臃肿,哦不&a…...
HTTP协议笔记
HTTP协议笔记 参考: (建议精读)HTTP灵魂之问,巩固你的 HTTP 知识体系 《透视 HTTP 协议》——chrono 目录: 1、说说你对HTTP的了解吧。 1. HTTP状态码。 2. HTTP请求头和响应头,其中包括cookie、跨域响…...
Joy-Con Toolkit:让Switch玩家掌控设备的开源管理方案
Joy-Con Toolkit:让Switch玩家掌控设备的开源管理方案 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit 为什么Switch玩家需要专属管理工具? 当你插入Switch游戏卡带时,是否担心…...
用Node.js和request-promise玩转EduCoder API:手把手教你搭建自己的实训答案库
用Node.js构建EduCoder实训数据采集系统的工程实践 在编程教育平台EduCoder上,实训关卡的设计往往需要学习者反复尝试和验证。作为开发者,我们能否通过技术手段实现实训数据的自动化采集与管理?本文将深入探讨如何基于Node.js生态构建一个稳定…...
SEO_从入门到精通,掌握SEO的核心操作步骤
<h2>SEO从入门到精通,掌握SEO的核心操作步骤</h2> <p>在当今的互联网时代,搜索引擎优化(SEO)已经成为任何网站或网页希望获得高流量、高曝光的关键技能。无论你是一个初学者,还是已经有一些SEO基础的…...
YOLOv8改进之TransformerHead:将检测头替换为轻量级Transformer预测层,捕捉全局上下文
摘要 在目标检测任务中,YOLOv8凭借其高效的架构和优异的性能表现,已成为工业界和学术界广泛应用的基准模型。然而,YOLOv8传统检测头基于卷积神经网络设计,虽能有效提取局部特征,但在建模全局上下文关系和长程依赖方面存在天然局限。针对这一问题,本文提出了一种创新的改…...
LuckyLilliaBot:NTQQ的终极OneBot协议插件完整指南
LuckyLilliaBot:NTQQ的终极OneBot协议插件完整指南 【免费下载链接】LuckyLilliaBot NTQQ的OneBot API插件 项目地址: https://gitcode.com/gh_mirrors/li/LuckyLilliaBot LuckyLilliaBot是一个基于TypeScript开发的NTQQ插件,为QQ客户端提供完整的…...
终极Windows音频路由指南:如何实现多设备音频分离的专业方案
终极Windows音频路由指南:如何实现多设备音频分离的专业方案 【免费下载链接】audio-router Routes audio from programs to different audio devices. 项目地址: https://gitcode.com/gh_mirrors/au/audio-router 你是否曾经遇到过这样的困扰:想…...
巨有科技智慧市集系统,数字化工具降本增效!
从城市商圈到景区古镇,从乡村田园到文创园区,各类市集遍地开花,但管理难题始终是制约行业发展的最大瓶颈。人工登记杂乱、对账结算繁琐、现场管控滞后、数据完全空白,一场中型市集就要耗费大量人力物力,大型市集更是纠…...
华为eNSP实战:三层交换机VLAN间通信配置避坑指南(附CE12800特殊命令)
华为eNSP三层交换机VLAN间通信实战:从基础配置到核心设备差异解析 在华为eNSP模拟器的学习过程中,三层交换机配置是网络工程师必须掌握的硬核技能。不同于传统二层交换,三层交换技术融合了路由与交换的优势,能够高效实现VLAN间通信…...
同花顺期货通指标编写指南:从零开始构建趋势波段共振系统(含避坑技巧)
同花顺期货通指标编写指南:从零开始构建趋势波段共振系统(含避坑技巧) 在期货交易中,技术指标是交易者不可或缺的分析工具。同花顺期货通作为国内主流的期货交易软件,其内置的指标编写功能为交易者提供了强大的自定义能…...
ComfyUI-WanVideoWrapper视频生成工具零基础快速部署实战教程
ComfyUI-WanVideoWrapper视频生成工具零基础快速部署实战教程 【免费下载链接】ComfyUI-WanVideoWrapper 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-WanVideoWrapper ComfyUI-WanVideoWrapper是一款功能强大的视频生成工具,它能让用户在Co…...
