从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器

上一章我们完成了netty服务启动的相关抽象(https://blog.csdn.net/money9sun/article/details/136025471),这一章我们再新增一个全局的服务启动类,方便后续扩展。

服务启动

新增的两个类如下:

定义一个接口IServer

java 复制代码
public interface IServer {

    /**
     * 服务启动
     * @throws Exception
     */
    void start() throws Exception;

    /**
     * 服务关闭
     * @throws Exception
     */
    void stop() throws Exception;

    /**
     * 服务重启
     * @throws Exception
     */
    void restart() throws Exception;

}

定义实现类 BasicServer

java 复制代码
import com.loveprogrammer.base.factory.ServerChannelFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;

/**
 * @ClassName BasicServer
 * @Description  网络服务启动实现
 * @Author admin
 * @Date 2024/2/4 16:25
 * @Version 1.0
 */
public class BasicServer implements IServer{
    Channel acceptorChannel;

    @Override
    public void start() throws Exception {
        acceptorChannel = ServerChannelFactory.createAcceptorChannel();
        acceptorChannel.closeFuture().sync();
    }
    @Override
    public void stop() throws Exception {
        if(acceptorChannel != null) {
            acceptorChannel.close().addListener(ChannelFutureListener.CLOSE);
        }
    }
    @Override
    public void restart() throws Exception {
        stop();
        start();
    }
}

启动类修改:

java 复制代码
        
        // 启动类启动
        try {
            IServer server = new BasicServer();
            server.start();
        } catch (Exception e) {
            LOGGER.error( "服务器启动失败",e);
        }

网络事件监听器

创建一个类,用于监听网络的变化,创建一个接口INetworkEventListener,里面包含3个方法,onConnected/onDisconnected/onExceptionCaught。依然创建在core组件中

java 复制代码
public interface INetworkEventListener {

    /**
     * 连接建立
     *
     * @param ctx ChannelHandlerContext
     */
    void onConnected(ChannelHandlerContext ctx);

    /**
     * 连接断开
     * * @param ctx ChannelHandlerContext
     */
    void onDisconnected(ChannelHandlerContext ctx);

    /**
     * 异常发生
     * * @param ctx ChannelHandlerContext
     * * @param throwable 异常
     */
    void onExceptionCaught(ChannelHandlerContext ctx, Throwable throwable);

}

监听器实现类 NetworkListener:

复制代码
package com.loveprogrammer.base.network.support;

import com.loveprogrammer.base.network.listener.INetworkEventListener;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NetworkListener implements INetworkEventListener {

    protected static final Logger logger = LoggerFactory.getLogger(NetworkListener.class);

    @Override
    public void onConnected(ChannelHandlerContext ctx) {
        logger.info("建立连接");
    }

    @Override
    public void onDisconnected(ChannelHandlerContext ctx) {
        logger.info("建立断开");
    }

    @Override
    public void onExceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
        logger.warn("异常发生", throwable);
    }
}

然后我们要修改TcpServerStringInitializer

java 复制代码
public class TcpServerStringInitializer  extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("framer",new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast("decoder", new StringDecoder());
        pipeline.addLast("encoder", new StringEncoder());
        INetworkEventListener listener = new NetworkListener();
        pipeline.addLast(new TcpMessageStringHandler(listener));
    }

}

TcpMessageStringHandler.java 修改如下

java 复制代码
package com.loveprogrammer.base.network.channel.tcp.str;

import com.loveprogrammer.base.network.listener.INetworkEventListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName TcpMessageStringHandler
 * @Description tcp消息处理类
 * @Author admin
 * @Date 2024/2/4 15:16
 * @Version 1.0
 */
public class TcpMessageStringHandler extends SimpleChannelInboundHandler<String> {
    private static final Logger logger = LoggerFactory.getLogger(TcpMessageStringHandler.class);

    private final INetworkEventListener listener;

    public TcpMessageStringHandler(INetworkEventListener listener) {
        this.listener = listener;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
        listener.onExceptionCaught(ctx,throwable);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        logger.info("数据内容:data=" + msg);
        String result = "我是服务器,我收到了你的信息:" + msg;
        result += "\r\n";
        ctx.writeAndFlush(result);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        listener.onConnected(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        listener.onDisconnected(ctx);
    }
}

上一章:

从零开始手写mmo游戏从框架到爆炸(二)--- 核心组件抽离与工厂模式创建-CSDN博客

下一章:

从零开始手写mmo游戏从框架到爆炸(四)--- session session-CSDN博客

全部源码详见:

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

分支:step-03

参考:

java游戏服务器开发: https://blog.csdn.net/cmqwan/category_7690685.html

相关推荐
海拥✘5 小时前
CodeBuddy终极测评:中国版Cursor的开发革命(含安装指南+HTML游戏实战)
前端·游戏·html
monstercl7 小时前
游戏资源传输服务器
运维·服务器·游戏
狐凄11 小时前
Python实例题:pygame开发打飞机游戏
python·游戏·pygame
Tech Synapse1 天前
Unity ML-Agents实战指南:构建多技能游戏AI训练系统
人工智能·游戏·unity
浮云中的神马-潘帅3 天前
一款独立于游戏外的键盘源按键辅助工具他来了
游戏·计算机外设
2301_780789663 天前
高防ip是怎么做到分布式防御的
分布式·网络协议·tcp/ip·游戏·ddos·高防ip·高防cdn
二狗哈3 天前
制作一款打飞机游戏39:鼠标控制
游戏·计算机外设
windwind20003 天前
发行基础:本地化BUG导致审核失败
游戏·青少年编程·编辑器·bug·创业创新·玩游戏
wgc2k4 天前
Java游戏服务器开发流水账(4)游戏的数据持久化
java·服务器·游戏
IP管家4 天前
多级路由器如何避免IP冲突
网络·网络协议·tcp/ip·游戏·智能路由器·ip