使用最新Netty实现一个简单的聊天程序

本文介绍如何利用Netty4.x构建一个简单的聊天程序,包括服务端和客户端的实现,以及消息的编解码。Netty是一个高性能、高可靠的网络应用框架,文章详细展示了ServerHandler、ClientHandler的实现,以及利用MessagePack进行高效编解码的方法。
摘要由CSDN通过智能技术生成

原文出自:http://blog.csdn.net/anxpp/article/details/52139155,转载请注明出处,想想!

1、概述

    Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

    官网:http://netty.io/

    目前最新的是版本是4.1.4(5.x版本官网已经弃用,不推荐使用)。

    Netty4.x同时也是原生支持Android的,所以后面的程序,放到android上也是可以正常运行的(亲测)。

    项目如果使用Maven开发,直接添加以下依赖即可:

 
 
 
  1. <dependency>
  2. <groupId>io.netty</groupId>
  3. <artifactId>netty-all</artifactId>
  4. <version>4.1.4.Final</version>
  5. </dependency>

2、实现服务端

    首先是消息处理类ServerHandler


  
  
  
  1. package com.anxpp.im.server.handler;
  2. import io.netty.channel.ChannelHandler;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import java.io.IOException;
  6. import com.anxpp.im.common.IMMessage;
  7. import com.anxpp.im.common.OnlineUser;
  8. import com.anxpp.im.server.config.BaseConfig;
  9. @ChannelHandler.Sharable
  10. public class ServerHandler extends ChannelInboundHandlerAdapter implements BaseConfig{
  11. private ChannelHandlerContext ctx;
  12. @Override
  13. public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
  14. System.err.println("服务端Handler创建...");
  15. super.handlerAdded(ctx);
  16. }
  17. @Override
  18. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  19. System.err.println("channelInactive");
  20. super.channelInactive(ctx);
  21. }
  22. /**
  23. * tcp链路建立成功后调用
  24. */
  25. @Override
  26. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  27. this.ctx = ctx;
  28. System.err.println("有客户端连接:"+ctx.channel().remoteAddress().toString());
  29. }
  30. /**
  31. * 发送消息
  32. */
  33. public boolean sendMsg(IMMessage msg) throws IOException {
  34. System.err.println("服务器推送消息:"+msg);
  35. ctx.writeAndFlush(msg);
  36. return msg.getMsg().equals("q") ? false : true;
  37. }
  38. @Override
  39. public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
  40. System.err.println("服务器接收到消息:"+msg);
  41. IMMessage message = (IMMessage)msg;
  42. if(OnlineUser.get(message.getReceiveId())==null){
  43. OnlineUser.put(message.getUid(), ctx);
  44. }
  45. ChannelHandlerContext c = OnlineUser.get(message.getReceiveId());
  46. if(c==null){
  47. message.setMsg("对方不在线!");
  48. OnlineUser.get(message.getUid()).writeAndFlush(message);
  49. }
  50. else
  51. c.writeAndFlush(message);
  52. }
  53. /**
  54. * 异常处理
  55. */
  56. @Override
  57. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
  58. System.err.println("与客户端断开连接:"+cause.getMessage());
  59. cause.printStackTrace();
  60. ctx.close();
  61. }
  62. }

    接收客户端连接,如果客户端没有连接过,就保存ChannelHandlerContext到Map中用于发送消息。然后判断消息接收方是否在线,若在线就直接发送消息,没有在线就返回“对方不在线”。当然,可以将消息发送者和消息接收者ID设置为相同就能仅开一个客户端自己跟自己聊天(类似Echo Server)。

    服务器程序Server


  
  
  
  1. package com.anxpp.im.server;
  2. import io.netty.bootstrap.ServerBootstrap;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.ChannelOption;
  6. import io.netty.channel.EventLoopGroup;
  7. import io.netty.channel.nio.NioEventLoopGroup;
  8. import io.netty.channel.socket.SocketChannel;
  9. import io.netty.channel.socket.nio.NioServerSocketChannel;
  10. import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 39
    评论
Netty一个高性能的异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。使用Netty框架来编写一个聊天程序涉及到以下几个步骤: 1. **搭建基础框架**:创建Netty服务器和客户端项目结构,设置主从Reactor线程模型,以及ChannelPipeline的配置。 2. **处理Channel事件**:编写ChannelHandler来处理各种事件,如连接建立、读写事件、异常事件等。 3. **编码和解码**:编写自定义的编码器(Encoder)和解码器(Decoder)来处理自定义协议的消息格式。 4. **业务逻辑处理**:实现聊天业务逻辑的Handler,如用户登录验证、消息广播、心跳检测等。 5. **客户端连接和交互**:编写客户端代码,实现连接服务器、用户交互界面以及消息的发送接收。 6. **并发控制**:如果用户量很大,需要考虑使用线程池、Future、Promise等来处理并发和异步操作。 7. **测试**:对聊天室进行测试,包括功能测试、性能测试和压力测试。 下面是一个简化的示例代码,展示了Netty中如何定义一个简单的服务器端ChannelHandler来处理客户端的连接事件: ```java import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; public class ChatServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast("stringDecoder", new StringDecoder()); ch.pipeline().addLast("stringEncoder", new StringEncoder()); ch.pipeline().addLast(new ChatServerHandler()); } } public class ChatServerHandler extends SimpleChannelInboundHandler<String> { @Override public void channelActive(ChannelHandlerContext ctx) { // 当客户端连接时触发 System.out.println("Client connected: " + ctx.channel().remoteAddress()); } @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { // 当读取客户端消息时触发 System.out.println("Received message: " + msg); // 广播消息给所有连接的客户端 ctx.channel().writeAndFlush("Server received: " + msg); } @Override public void channelInactive(ChannelHandlerContext ctx) { // 当客户端断开连接时触发 System.out.println("Client disconnected: " + ctx.channel().remoteAddress()); } } ``` 在上述代码中,`ChatServerInitializer` 负责初始化客户端通道 `SocketChannel`,添加了字符串解码器和编码器以及聊天服务器处理器 `ChatServerHandler`。`ChatServerHandler` 处理了连接激活、读取消息和连接非活跃事件。
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值