【Netty4.x】Unity客户端与Netty服务器的网络通信
一、开发环境
- 开发工具:eclipse-jee-indigo-SR2-win32-x86_64
- JDK版本:JDK1.7
- 操作系统:windows-64
Netty库下载与项目导入
Netty库 netty-all-4.1.1.Final-sources 可从 Netty官方网站 下载,在网站的【Downloads】板块选择下载 netty-all-4.1.1.Final-sources。
下载完成后,创建一个Java工程,选中项目右键,依次选择 Properties -> Java Build Path -> Add External JARS,将 netty-all-4.1.1.Final.jar 包导入到项目中。
二、Netty服务器端开发
2.1 代码示例
服务启动类 HttpServer
创建服务启动类 HttpServer,该类的作用类似于Tomcat服务器,有开启和关闭服务器的功能。其启动方式为右键点击类文件,选择 Run As -> Java Application。以下是 HttpServer 类的代码:
package com.lll.game;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class HttpServer {
private static Log log = LogFactory.getLog(HttpServer.class);
public static void main(String[] args) throws Exception {
HttpServer server = new HttpServer();
log.info("服务已启动...");
server.start(8844);
}
public void start(int port) throws Exception {
// 配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ServerHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128) // 最大客户端连接数为128
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放线程池资源
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
ServerHandler 类
创建 ServerHandler 类来负责对网络事件进行读写操作。以下是 ServerHandler 类的代码:
package com.lll.game;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class ServerHandler extends ChannelHandlerAdapter {
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
System.out.println(ctx.channel().id() + "进来了");
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
super.handlerRemoved(ctx);
System.out.println(ctx.channel().id() + "离开了");
}
}
提示:本书作者使用的是Netty 5.0版本,但在官方下载时仅能找到4.x版本的包(据说Netty 5.0已被官方废弃)。不同版本中 ChannelHandler 申明的方法有所不同。
2.2 Netty 5.x 与 4.x 代码上的差异
在Netty 4.x中,ChannelHandlerAdapter 里的 channelRead 方法位于 ChannelInboundHandlerAdapter 抽象类中。和Netty 5.x一样,ChannelInboundHandlerAdapter 也是基于 ChannelHandler 接口。这使得用户能够方便地进行业务逻辑定制,例如打印日志、统一封装异常信息、性能统计和消息编码解码等。ChannelInboundHandlerAdapter 的UML图可进一步展示其结构关系。
2.3 4.x ServerHandler 类
package com.game.lll.net;
import java.util.Date;
// 此处原代码未完整,后续代码需补充完整才能正常使用
以上就是Netty 4.x服务器端开发的相关内容,后续可以在此基础上进一步完善功能,实现与Unity客户端的网络通信。