使用最新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
    评论
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值