netty服務端監聽客戶端連線加入和斷開事件

NemoHero發表於2020-11-12
package com.ahies.stm.app.gatenetty;

import com.ahies.stm.app.centerControl.object.protocol.ControlProtocol;
import com.ahies.stm.app.centerControl.object.service.ControlObjectService;
import com.ahies.stm.app.synthesizes.appoint.service.AppointMemberService;
import com.ahies.stm.app.ticketsys.gatenetty.GatelProtocol;
import com.ahies.stm.app.util.HexUtil;
import com.ahies.stm.app.util.SpringContextUtil;
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.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.net.InetSocketAddress;


public class GateTcpServerHandler extends SimpleChannelInboundHandler<Object> {
    public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 用於獲取客戶端發來的資料資訊
        GatelProtocol body = (GatelProtocol) msg;
        System.out.println("接收到客戶端發來的訊息=="+msg.toString());
        AppointMemberService appointMemberService = (AppointMemberService) SpringContextUtil.getBean(AppointMemberService.class);
        appointMemberService.handleMsg(body,ctx);


    }

    /**
     * 當有客戶端連線時,handlerAdded會執行,就把該客戶端的通道記錄下來,加入佇列
     *連線第1步
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

        Channel inComing = ctx.channel();//獲得客戶端通道
        //通知其他客戶端有新人進入
        channels.add(inComing);//加入佇列
        super.handlerAdded(ctx);
    }

  
// 連線第2步
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel inComing = ctx.channel();
        AttributeKey<String> host_channel_key = AttributeKey.valueOf("channel-host");
        Attribute<String> attr = inComing.attr(host_channel_key);
        InetSocketAddress socketAddress = (InetSocketAddress) inComing.remoteAddress();
        String host = socketAddress.getHostString();
        attr.set(host);
        System.out.println("[" + inComing.remoteAddress() + "]: 線上");
        super.channelActive(ctx);
    }

    // 斷開連線 第1步
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel inComing = ctx.channel();
        System.out.println("[" + inComing.remoteAddress() + "]: 離線");
        super.channelInactive(ctx);
    }

  /**
     * 斷開連線 第2步
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {


        Channel outComing = ctx.channel();//獲得客戶端通道
        channels.remove(outComing);
        super.handlerRemoved(ctx);
        ctx.channel().close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("exceptionCaught!" + cause);
        cause.printStackTrace();
        channels.remove(ctx.channel());
        ctx.close();
    }
}

 

相關文章