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

  • 相关阅读:
    SQL 三种Join关联示例
    EntityFramework 更新 整个记录全部字段不确定字段
    C# 生成Excel 报错COMException(0x800A03EC)
    EntityFramework4 几种报错解决方法
    Machine learning lecture2 note
    谷歌360度街景拍摄车对日本核电站污染隔离区进行拍摄
    android电池电量状态代码
    唠骚 2013年终奖
    互联网手机的围城:小米顶多再风光一年(转载)
    AIX下c3p0连接池问题
  • 原文地址:https://www.cnblogs.com/sidesky/p/12726638.html
Copyright © 2011-2022 走看看