zoukankan      html  css  js  c++  java
  • 基于netty的聊天室(保持和获取客户端channel)

    package chatroom;

    import io.netty.channel.Channel;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.channel.group.ChannelGroup;
    import io.netty.channel.group.DefaultChannelGroup;
    import io.netty.util.concurrent.GlobalEventExecutor;

    /**
    * @Author: Usher
    * @Description:
    * 回调处理类,继承SimpleChannelInboundHandler处理出站入站数据,模板设计模式,让主要的处理逻辑保持不变,让变化的步骤通过接口实现来完成
    */
    public class ChatServerHandler extends SimpleChannelInboundHandler <String>{


    public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    /**
    * 当有客户端连接时,handlerAdded会执行,就把该客户端的通道记录下来,加入队列
    * @param ctx
    * @throws Exception
    */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
    Channel inComing = ctx.channel();//获得客户端通道
    //通知其他客户端有新人进入
    for (Channel channel : channels){
    if (channel != inComing)
    channel.writeAndFlush("[欢迎: " + inComing.remoteAddress() + "] 进入聊天室! ");
    }

    channels.add(inComing);//加入队列
    }

    /**
    * 断开连接
    * @param ctx
    * @throws Exception
    */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
    Channel outComing = ctx.channel();//获得客户端通道
    //通知其他客户端有人离开
    for (Channel channel : channels){
    if (channel != outComing)
    channel.writeAndFlush("[再见: ]" + outComing.remoteAddress() + " 离开聊天室! ");
    }

    channels.remove(outComing);
    }

    /**
    * 每当从客户端有消息写入时
    * @param channelHandlerContext
    * @param s
    * @throws Exception
    */
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
    Channel inComing = channelHandlerContext.channel();

    for (Channel channel : channels){
    if (channel != inComing){
    channel.writeAndFlush("[用户" + inComing.remoteAddress() + " 说:]" + s + " ");
    }else {
    channel.writeAndFlush("[我说:]" + s + " ");
    }
    }
    }

    /**
    * 当服务器监听到客户端活动时
    * @param ctx
    * @throws Exception
    */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    Channel inComing = ctx.channel();
    System.out.println("[" + inComing.remoteAddress() + "]: 在线");
    }

    /**
    * 离线
    * @param ctx
    * @throws Exception
    */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    Channel inComing = ctx.channel();
    System.out.println("[" + inComing.remoteAddress() + "]: 离线");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    Channel inComing = ctx.channel();
    System.out.println(inComing.remoteAddress() + "通讯异常!");
    ctx.close();
    }
    }
    ————————————————
    版权声明:本文为CSDN博主「Usher_Ou」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/usher_ou/java/article/details/80919350

  • 相关阅读:
    浏览器图片渲染优化教程
    C#把 DataTable转换为Model实体
    .NET静态变量与静态方法并发的问题
    三种方法查看MySQL数据库的版本
    Mysql 存储引擎 InnoDB与Myisam的主要区别
    dotnet core 出现Can not find runtime target for framework '.NETCoreApp,Version=v1.6' 的解决办法
    细说 C# 中的 IEnumerable和IEnumerator接口
    ASP.NET CORE dotnet run 命令使用debug方式运行
    安装了插件情况下 强制开启火狐浏览器的多进程功能
    JSON 字符串中的中括号和大括号区别详解
  • 原文地址:https://www.cnblogs.com/sidesky/p/12726638.html
Copyright © 2011-2022 走看看