目录
-
- 引言
- 技术选型
- 正文
-
- 创建基础架构
-
- IDEA创建项目
- 添加Netty监听端口
- 编写客户端进行测试
- 总结
引言
由于现在java web太卷了,所以各位同行可以考虑换一个赛道,做游戏还是很开心的。
本篇教程给新人用于学习游戏服务器的基本知识,给新人们一些学习方向,有什么错误的地方欢迎各位同行进行讨论。
技术选型
本篇教程预计使用Java+Redis+Mongo
正文
本着先完成再完美的原则,从最简单的echo服务器开始。
![从零开始搭建游戏服务器 第一节 创建一个简单的服务器架构_第1张图片](http://img.e-com-net.com/image/info8/0061d1f4fb1e410c98b445f63a86c53c.jpg)
Echo服务器就是,客户端发什么数据,服务端就原样返回回去。
创建基础架构
IDEA创建项目
![从零开始搭建游戏服务器 第一节 创建一个简单的服务器架构_第2张图片](http://img.e-com-net.com/image/info8/ce410bcb6baa4939b68ee5fd06033409.jpg)
我这边用Gradle进行依赖管理,使用的版本为 gradle8.0.2, openjdk19.
修改build.gradle导入几个基础开发包。
dependencies {
//网络
implementation group: 'io.netty', name: 'netty-all', version: '4.1.90.Final'
//spring
implementation group: 'org.springframework', name: 'spring-context', version: '6.0.6'
//log
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.36'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.11'
implementation group: 'ch.qos.logback', name: 'logback-access', version: '1.2.11'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.11'
//lombok
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.24'
}
创建Bean配置类
@Configuration
@ComponentScan(basePackages = {"com.wfgame"})
public class GameBeanConfiguration {
}
创建主类
@Component
@Slf4j
public class GameMain {
public static void main(String[] args) {
// 初始化Spring
AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(GameBeanConfiguration.class);
springContext.start();
log.info("server start!");
}
}
运行一下,正常输出server start!
我们会发现,程序执行后马上停止了,对于游戏服务器来说,我们需要保持运行状态,等待玩家接入进行游戏。所以我们main中增加一个循环,不停读取控制台输入,当读取到控制台输入stop时,我们再进行停服。
修改main方法如下:
public static void main(String[] args) {
// 初始化Spring
AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(GameBeanConfiguration.class);
springContext.start();
log.info("server start!");
//region 处理控制台输入,每秒检查一遍 stopFlag,为true就跳出循环,执行关闭操作
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 设置循环使服务器不立刻停止
while (true) {
if (stopFlag) {
log.info("receive stop flag, server will stop!");
break;
}
// 每次循环停止一秒,避免循环频率过高
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//处理控制台指令
try {
if (br.ready()) {
String cmd = br.readLine().trim();
if (cmd.equals("stop")) {//正常关服
stopFlag = true;
log.info("Receive stop flag, time to stop.");
} else {
log.info("Unsupported cmd:{}", cmd);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//停掉虚拟机
System.exit(0);
}
这样我们就获得了一个可以控制停服的服务器。当我们控制台输入stop时,程序结束运行。
添加Netty监听端口
要与客户端进行TCP连接,需要建立socket通道,然后通过socket通道进行数据交互。
传统BIO一个线程一个连接,有新的连接进来时就要创建一个线程,并持续读取数据流,当这个连接发送任何请求时,会对性能造成严重浪费。
NIO一个线程通过多路复用器可以监听多个连接,通过轮询判断连接是否有数据请求。
Netty对java原生NIO进行了封装,简化了代码,便于我们的使用。
Netty的包我们之前已经导入过了,直接拿来用即可。
首先我们创建一个Netty自定义消息处理类。
@Sharable
public class NettyMessageHandler extends SimpleChannelInboundHandler