netty服務端與客戶端通信實現牛牛文字遊戲

客戶端邏輯
/**
 * @Description:  
 * @version: v1.0.0
 * @author: wbl
 * @date: 2020年1月13日 下午1:22:29
 */
public class ClientHandler extends ChannelInboundHandlerAdapter{
    public static String Name = "";
      @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
          
        }
    /**
     * @Description:
     *
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            if(null == msg) return;
            String data = (String) msg;//收到數據
            
            
            if("牛牛客戶端登錄成功!".equals(data)){
                System.out.println("牛牛客戶端啓動成功!");
                System.out.println("請選擇序號:1.登錄   2.註冊");
                String cli = read();
                if("1".equals(cli)){
                    System.out.println("請輸入用戶名:");
                    Name = read();
                    ctx.channel().writeAndFlush("wbl1"+Name);
                }else if("2".equals(cli)){
                    System.out.println("請輸入新用戶名:");
                    Name = read();
                    ctx.channel().writeAndFlush("wbl2"+Name);
                }else{
                    System.out.println("指令輸入有誤,請重新輸入:1.登錄   2.註冊");
                    Name = read();
                    ctx.channel().writeAndFlush("wbl2"+Name);
                }
                
            }else if(data.contains("wbl2")||data.contains("wbl3")){
                System.out.println(data.substring(4));
                
                System.out.println("請選擇序號:1.登錄   2.註冊");
                while(true){
                    String cli = read();
                    if("1".equals(cli)){
                        System.out.println("請輸入用戶名:");
                        Name = read();
                        ctx.channel().writeAndFlush("wbl1"+Name);
                        break;
                    }else if("2".equals(cli)){
                        System.out.println("請輸入新用戶名:");
                        Name = read();
                        ctx.channel().writeAndFlush("wbl2"+Name);
                        break;
                    }else{
                        System.out.println("指令輸入有誤,請重新輸入:1.登錄   2.註冊");
                    }
                }
                
            }else if(data.contains("wbl1")||data.contains("wbl4")){
                System.out.println(data.substring(4));
                System.out.println("百人牛牛遊戲開始!請輸入命令序號:1隨機搶莊入桌(匹配) 2.查詢賬戶信息  3.退出");
                while(true){
                    String cli = read();
                    if("1".equals(cli)){
                        ctx.channel().writeAndFlush("wbl3"+Name);
                        break;
                    }else if("2".equals(cli)){
                        ctx.channel().writeAndFlush("wbl4"+Name);
                        break;
                    }else if("3".equals(cli)){
                        ctx.channel().writeAndFlush("wbl5"+Name);
                        System.out.println("客戶端正常登出,"+Name+"賬號非常安全!");
                        System.exit(1);
                    }else{
                        System.out.println("指令輸入有誤,請重新輸入:1隨機搶莊入桌(匹配)   2.查詢賬戶信息  3.退出");
                    }
                }
            
            }else if(data.contains("wbl5") || data.contains("wbl6")){//開始返回結果
                System.out.println(data.substring(4));
                while(true){
                    System.out.println("\n\n百人牛牛遊戲開始!請輸入命令序號:1隨機搶莊入桌(匹配)  2.查詢賬戶信息  3.退出");
                    String cli = read();
                    if("1".equals(cli)){
                        ctx.channel().writeAndFlush("wbl3"+Name);
                        break;
                    }else if("2".equals(cli)){
                        ctx.channel().writeAndFlush("wbl4"+Name);
                        break;
                    }else if("3".equals(cli)){
                        System.out.println("客戶端正常登出,"+Name+"賬號非常安全!");
                        ctx.channel().writeAndFlush("wbl5"+Name);
                        System.exit(1);
                    }else{
                        System.out.println("指令輸入有誤,請重新輸入:1隨機搶莊入桌(匹配)  2.查詢賬戶信息  3.退出");
                    }
                }
            }
        
    }
    /**
     * @Description:
     *
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("客戶端異常關閉,遊戲結束!");
        try{
            ctx.channel().writeAndFlush("wblquit"+Name);
        }catch(Exception e){
            System.out.println("客戶端中斷,未通知到服務端,將延時5分鐘,客戶端在服務器自動登出");
        }
        ctx.close();
    }
    
      /** 空閒次數 */
    private int idle_count = 1;
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
        
        if (obj instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) obj;
            if (IdleState.WRITER_IDLE.equals(event.state())) { // 如果寫通道處於空閒狀態就發送心跳命令
                  String str = "xintiao";
                  ctx.channel().writeAndFlush(str);
            }
        }
    }
    
    
    public static String read() throws Exception{  
        String str = "";
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            str = sc.next();
           break;
        }
        return str;    
    }

    
}

服務端邏輯


/**
 * @Description:  
 * @version: v1.0.0
 * @author: wbl
 * @date: 2020年1月13日 下午1:22:29
 */
public class DivServerHandler  extends ChannelInboundHandlerAdapter{
    public static Map<String,String> user = new HashMap();//username:on/off_jinbi
    public static List<String> user_group =  new ArrayList();
    public static List<ChannelHandlerContext> user_group_client = new ArrayList();

     @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
             System.out.println("有新的客戶端登錄:"+ ctx.channel().remoteAddress().toString());
             DivChannelInitializer.client_active ++;
     }
    
      @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {//ctx.close();//close會自動調用本方法
            DivChannelInitializer.client_active --;
            
            
            
      }
        
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            String body = (String)msg;
            if("logon".equals(body)){
                ctx.channel().writeAndFlush("牛牛客戶端登錄成功!");
                return;
            }else if(body.contains("wbl1")){//登錄
                String name = body.substring(4);
                if(user.containsKey(name)){
                    user.put(name, "1_"+yue(name));
                    ctx.channel().writeAndFlush("wbl1牛氣沖天的用戶-"+name +"-登錄成功!"
                            +"  賬號餘額:"+yue(name)
                            +"  當前在線人數:"+currentOnLine());
                    return;
                }else{
                    ctx.channel().writeAndFlush("wbl2"+body.substring(4) +"-用戶未註冊!");
                    return ;
                }
            }else if(body.contains("wbl2")){//註冊
                String name = body.substring(4);
                if(user.containsKey(name)){
                    ctx.channel().writeAndFlush("wbl3"+body.substring(4) +"-用戶已註冊,請換個其他名字!");
                    return;
                }else{
                    user.put(body.substring(4), "1_20");
                    
                    ctx.channel().writeAndFlush("wbl4牛氣沖天的用戶-"+body.substring(4) +"-註冊並登錄成功!");
                    return;
                }
            }else if(body.contains("wbl3")){//開始
                String name = body.substring(4);
                user_group.add(name);
                user_group_client.add(ctx);
                
                int num = currentOnLine();
                if(user_group_client.size() >=2){
                    String resu = NiuInit.init();
                    System.out.println("發佈遊戲結果:"+resu);
                    for(int j = 0;j < user_group_client.size();j++){
                        ChannelHandlerContext gr = user_group_client.get(j);
                        gr.channel().writeAndFlush("wbl5" + resu);
                    }
                    user_group_client.clear();
                    user_group.clear();
                    Thread.sleep(5000);
                }

            }else if(body.contains("wbl4")){//查詢
                String name = body.substring(4);
                String kvalue = user.get(name);
                kvalue = kvalue.substring(2);
                ctx.channel().writeAndFlush("wbl6 牛牛用戶"+name +"當前帳號餘額爲:" + kvalue);
            }else if(body.contains("wbl5")){//退出
                String name = body.substring(4);
                String kvalue = user.get(name);
                user.put(name,"0_"+kvalue.substring(2));
            }
            
            
            
        }
        
        /**
         * 超時處理,如果HEARTBEAT_TIME秒沒有收到客戶端的心跳,就觸發;
         */
        /** 空閒次數 */
        private int idle_count = 1;
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
             if (obj instanceof IdleStateEvent) {
                 System.out.println("服務端收到xintiao....");
                 IdleStateEvent event = (IdleStateEvent) obj;
                 if (IdleState.READER_IDLE.equals(event.state())) {
                     if (idle_count > 2) {
                         System.out.println("超過兩次無客戶端請求,關閉該channel");
                         ctx.channel().close();
                     }
                     System.out.println("已等待"+DivChannelInitializer.HEARTBEATTIME
                             +DivChannelInitializer.TIME_UNIT
                             +"還沒收到客戶端發來的消息");
                     idle_count++;
                 }
             } else {
                 super.userEventTriggered(ctx, obj);
             }
        }
    
        /**
         * 當發生異常時,打印異常 日誌,釋放客戶端資源
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            /**釋放資源*/
            System.out.println("退出遊戲!");
            ctx.close();
        }
        
        //獲取當前在線人數
        public  int currentOnLine(){
            int len = 0;
            for(String value : user.values()){
                if(value.contains("1_")){
                    len ++;
                }
            }
            return len;
        }
        //獲取當前用戶的金幣數
        public static  String yue(String name){
            String value = user.get(name);
            String jb = value.substring(2);
            return jb;
        }
        //寫入金幣數
        public static  void write(String name,int mon){
            user.put(name, "1_"+mon);
        }
}

發佈了10 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章