java版QQ斗地主Socket心跳机制实现思路

小项目开源地址:https://gitee.com/ansatsing/QQLandlords

简要概述:
  客户端登录成功后,就持续每隔3秒向服务器端发送心跳包!服务器端每收到一次心跳包就更新lastReveHeatTime的变量值;服务器在启动的时候就开启
  一个只针对入座玩家的监听线程,这个线程每隔10秒钟就处理一批超过10秒未发送心跳包的掉线玩家从而以便同步游戏大厅的位置信息!
数据机构:
  Player实体类增加属性: private long lastReveHeatTime;//最后一次收到心跳包协议的时间:单位毫秒

  客户端增加一个心跳协议消息类:HeartBeatProt;注意:服务器端无需增加!

  

 1 package com.ansatsing.landlords.protocol;
 2 
 3 import com.alibaba.fastjson.JSON;
 4 import com.ansatsing.landlords.entity.Player;
 5 
 6 import java.io.Serializable;
 7 
 8 /**
 9  * socket心跳协议--主要检测客户端的是否还连接!
10  */
11 public class HeartBeatProt extends AbstractProtocol implements Serializable {
12     private String msg = "我还活着呢!";
13 
14     public String getMsg() {
15         return msg;
16     }
17 
18     public HeartBeatProt(Player player) {
19         super.player = player;
20     }
21 
22     @Override
23     public void sendMsg() {
24         super.sendMsg(this.getClass().getName()+ JSON.toJSONString(this));
25     }
26 }

 


客户端:
  增加一个每隔3秒就发送一个心跳包给服务器端的线程:com.ansatsing.landlords.client.thread
  

package com.ansatsing.landlords.client.thread;

import com.ansatsing.landlords.entity.Player;
import com.ansatsing.landlords.protocol.AbstractProtocol;
import com.ansatsing.landlords.protocol.HeartBeatProt;

import java.util.concurrent.TimeUnit;

/**
 * 心跳线程
 */
public class HeartBeatThread implements  Runnable {
    private volatile boolean isStop = false;
    private Player player;

    public HeartBeatThread(Player player) {
        this.player = player;
    }
    public void stop(){
        this.isStop = true;
    }
    public void run() {
        while(!isStop){
            AbstractProtocol heartBeatProt = new HeartBeatProt(player);
            heartBeatProt.sendMsg();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

  

服务器端
  增加一个专门监听超过10秒未发送心跳包的掉线客户端,监听只针对入座的玩家!

  

 1 package com.ansatsing.landlords.server.thread;
 2 
 3 import com.ansatsing.landlords.entity.Player;
 4 
 5 import java.io.IOException;
 6 import java.util.Iterator;
 7 import java.util.Map;
 8 import java.util.concurrent.TimeUnit;
 9 
10 /**
11  * 监听那些玩家掉线了,掉线了就踢掉:主要针对入座位置的玩家,没有入座的玩家不监听
12  */
13 public class HeartBeatMonitor implements Runnable {
14     private Map<Integer, Player> playerMap;;
15     public HeartBeatMonitor(Map<Integer, Player> playerMap){
16         this.playerMap = playerMap;
17     }
18     public void run() {
19         while (true){
20             try {
21                 TimeUnit.SECONDS.sleep(10);
22             } catch (InterruptedException e) {
23                 e.printStackTrace();
24             }
25           Iterator iterator = playerMap.entrySet().iterator();
26             while(iterator.hasNext()){
27                 Map.Entry<Integer,Player> entry = (Map.Entry<Integer,Player>)iterator.next();
28                 Player player = entry.getValue();
29                 if(System.currentTimeMillis() - player.getLastReveHeatTime() > 10000 ){
30                     if(player.getSocket() != null){
31                         try {
32                             player.setUnnormalExited(true);
33                             player.getSocket().close();
34                         } catch (IOException e) {
35                             e.printStackTrace();
36                         }
37                     }
38                 }
39             }
40         }
41     }
42 }

 

如有不对,欢迎指教!谢谢!或者有更好的思路欢迎留言直接我,本人是菜鸟!

转载于:https://www.cnblogs.com/ansating/p/7832991.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值