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

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

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

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

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

ServerTag.java

public interface ServerTag {

    /***
     * 打招呼
     */
    int TAG_HELLO_HI = 1;

}

ServerTopic.java

public interface ServerTopic {

    /***
     * 问候
     */
    int TOPIC_HELLO = 1;

}

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

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.reflections
            reflections
            0.9.10
        

        
            com.loveprogrammer
            eternity-common
            1.0-SNAPSHOT
        

        
            com.loveprogrammer
            eternity-command
            1.0-SNAPSHOT
        
    

在core中增加一个文件夹

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

创建两个注解:

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 handlerMap = new HashMap<>();

    @Override
    public void run(String... args) throws Exception {
        // 找到所有实现类
        Reflections reflections = new Reflections("com.loveprogrammer.base.network.command.handler");
        // 获取在指定包扫描的目录所有的实现类
        Set> classes = reflections.getSubTypesOf(BaseHandler.class);
        for (Class 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游戏,游戏,java,mmo,spring,boot)