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

本文主要是介绍从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

服务启动

新增的两个类如下:

定义一个接口IServer  

public interface IServer {/*** 服务启动* @throws Exception*/void start() throws Exception;/*** 服务关闭* @throws Exception*/void stop() throws Exception;/*** 服务重启* @throws Exception*/void restart() throws Exception;}

定义实现类 BasicServer

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;@Overridepublic void start() throws Exception {acceptorChannel = ServerChannelFactory.createAcceptorChannel();acceptorChannel.closeFuture().sync();}@Overridepublic void stop() throws Exception {if(acceptorChannel != null) {acceptorChannel.close().addListener(ChannelFutureListener.CLOSE);}}@Overridepublic void restart() throws Exception {stop();start();}
}

 启动类修改:

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

网络事件监听器

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

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);@Overridepublic void onConnected(ChannelHandlerContext ctx) {logger.info("建立连接");}@Overridepublic void onDisconnected(ChannelHandlerContext ctx) {logger.info("建立断开");}@Overridepublic void onExceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {logger.warn("异常发生", throwable);}
}

然后我们要修改TcpServerStringInitializer

public class TcpServerStringInitializer  extends ChannelInitializer<SocketChannel> {@Overrideprotected 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 修改如下

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;}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {listener.onExceptionCaught(ctx,throwable);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {super.channelRead(ctx, msg);}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {logger.info("数据内容:data=" + msg);String result = "我是服务器,我收到了你的信息:" + msg;result += "\r\n";ctx.writeAndFlush(result);}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {listener.onConnected(ctx);}@Overridepublic 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

这篇关于从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

springboot的调度服务与异步服务使用详解

《springboot的调度服务与异步服务使用详解》本文主要介绍了Java的ScheduledExecutorService接口和SpringBoot中如何使用调度线程池,包括核心参数、创建方式、自定... 目录1.调度服务1.1.JDK之ScheduledExecutorService1.2.spring

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

MyBatis-Flex BaseMapper的接口基本用法小结

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具... 目录MyBATis-Flex简单介绍特性基础方法INSERT① insert② insertSelec