Netty学习笔记之二——Echo客户端

Echo客户端

Echo,如同Linux的Echo命令,就是打印输出的内容,它的工作内容:

  • 连接服务器
  • 发送信息
  • 等待和接收从服务器返回的同样的信息
  • 关闭连接

使用ChannelHandler实现客户端业务逻辑

如同服务器一样,使用ChannelInboundHandler接口来处理数据。服务器继承了ChannelInboundHandlerAdapter,这里客户端我们使用SimpleChannelInboundHandler来处理所有的任务,需要覆写三个方法:
- channelActive() - 服务器的连接被建立后调用
- channelRead0() - 从服务器收到数据后调用
- exceptonCaught() - 捕获一个异常时调用
代码如下:

// 1.@Sharable标记这个类的实例可以在 channel 里共享
@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 2.当被通知该channel是活动的时候就发送消息
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks !", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        // 3.记录接收到消息
        System.out.println("Client received: " + msg.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 4.捕获错误,并关闭连接
        cause.printStackTrace();
        ctx.close();
    }
}

注:
1、建立连接后,channelActive()方法被调用一次,我们使用Netty编码一个字符串,发送到服务器。
2、覆写channelRead0()方法,在接收到数据时调用。(注意,由服务器发送的消息可以以块的形式被接收。如:当服务器发送 5 个字节是不是保证所有的 5 个字节会立刻收到,即使是只有 5 个字节,channelRead0() 方法可被调用两次,第一次用一个ByteBuf(Netty的字节容器)装载3个字节和第二次一个 ByteBuf 装载 2 个字节。唯一要保证的是,该字节将按照它们发送的顺序分别被接收。 (注意,这是真实的,只有面向流的协议如TCP))

SimpleChannelInboundHandler vs. ChannelInboundHandler

何时用这两个要看具体业务的需要。在客户端,当 channelRead0() 完成,我们已经拿到的入站的信息。当方法返回时,SimpleChannelInboundHandler 会小心的释放对 ByteBuf(保存信息) 的引用。而在 EchoServerHandler,我们需要将入站的信息返回给发送者,由于 write() 是异步的,在 channelRead() 返回时,可能还没有完成。所以,我们使用 ChannelInboundHandlerAdapter,无需释放信息。最后在 channelReadComplete() 我们调用 ctxWriteAndFlush() 来释放信息。

客户端代码

客户端引导需要 host 、port 两个参数连接服务器。

public class EchoClient {
    private final String host;
    private final int port;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            // 1.客户端创建Bootstrap,服务器创建的是ServerBootstrap
            Bootstrap b = new Bootstrap();
            // 2.指定EventLoopGroup来处理客户端事件,因为用了NIO传输,所以用NioEventLoopGroup的实现
            b.group(group)
                    // 3.使用的 channel 类型是一个用于 NIO 传输
                    .channel(NioSocketChannel.class)
                    // 4.设置服务器的 InetSocketAddress
                    .remoteAddress(new InetSocketAddress(host, port))
                    // 5.当建立一个连接和一个新的通道时,创建添加到 EchoClientHandler 实例到channel pipeline
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            // 6.连接到远程;等待连接完成
            ChannelFuture cf = b.connect().sync();
            // 7.阻塞直到 Channel 关闭
            cf.channel().closeFuture().sync();
        } finally {
            // 8.调用 shutdownGracefully() 来关闭线程池和释放所有资源
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("Usage: " + EchoClient.class.getSimpleName() + "<host> <port>");
            return;
        }
        final String host = args[0];
        final int port = Integer.parseInt(args[1]);
        new EchoClient(host, port).start();
    }
}

流程:
1、创建一个Bootstrap来初始化客户端。
2、一个NioEventLoopGroup实例被分配给处理该事件的处理,这包括创建新的连接和处理入站和出站数据。
3、创建一个InetSocketAddress以连接到服务器。
4、连接好服务器之时,将安装一个EchoClientHandler在pipeline,处理业务逻辑。
5、之后Bootstrap.connect()被调用连接到远程的的服务器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。如果我理解正确的话,你想了解如何搭建一个使用Netty作为游戏服务器的Unity客户端。以下是一些大致的步骤: 1. 首先,你需要创建一个Unity项目并设置其为2D或3D游戏项目,具体取决于你的游戏类型。在Unity中,你可以使用C#编写客户端代码。 2. 在Unity中,你需要使用Socket类或TcpClient类等网络库来与Netty服务器进行通信。你需要在客户端上实现一个类似于Socket或TcpClient的类来进行网络通信。 3. 与服务器建立连接。在Unity中,你可以使用类似于下面的代码来建立连接。 ``` TcpClient client = new TcpClient(); client.Connect("127.0.0.1", 8888); ``` 4. 在客户端上实现收发消息的方法。你可以通过使用NetworkStream类来发送和接收消息。你需要在客户端上实现类似于下面的代码来发送消息。 ``` NetworkStream stream = client.GetStream(); byte[] data = Encoding.UTF8.GetBytes(message); stream.Write(data, 0, data.Length); ``` 5. 在客户端上解析从服务器返回的数据。你可以使用类似于下面的代码来解析从服务器返回的数据。 ``` byte[] buffer = new byte[1024]; int bytes = stream.Read(buffer, 0, buffer.Length); string data = Encoding.UTF8.GetString(buffer, 0, bytes); ``` 6. 在Unity中实现游戏逻辑。你需要在客户端上实现游戏逻辑以响应从服务器收到的数据。例如,你可以在客户端上实现一个类似于下面的代码来处理从服务器接收到的游戏数据。 ``` void HandleGameMessage(string message) { // 解析收到的消息 // 处理游戏逻辑 } ``` 希望这些步骤可以帮助你开始使用Netty作为游戏服务器的Unity客户端。当然,具体的实现还需要根据你的游戏类型和需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值