服务器统计当前在线人数

我们项目中APP端会定时比如10分钟发送包给服务器表示他还在线,然后服务器收到包后会在数据库一个表的online字段显示在线情况(1表示在线,0表示不在线),我统计的时候是根据1和0来查找当前在线人数的,但这中间有一个问题,比如一个用户在这10分钟之类下线了,但我服务器并不知道他下线了,统计的时候还是会统计为在线,请问有什么方法或者思路能统计到当前在线的人数吗

下线之前(或者退出app之前)发送请求更新数据库不就行了

app应该都有心跳机制的,用户强退后,服务器发送心跳,客户端没有响应就证明客户端掉线,你就可以更改状态了。而且心跳时间都是很短的所以影响很小

服务器发送心跳,客户端没有响应就证明客户端掉线,你就可以更改状态了。而且心跳时间都是很短的所以影响很小

在APP端退出时,向服务器发送退出请求,如果APP是被强退的,可以在APP的销毁方法里追加向服务器发送下线的请求,服务器收到请求后重围状态就可以了。

可以加入定时发送获取在线状态的功能,比如在平时无需查看在线状态时数据库不返回,需要查看时在客户端发起请求后,服务端将时间一起返回,并让客户端在该时间点向服务端发送请求。

如是使用TCP通信方式的话,就很好办了。
建立TCP的心跳机制,客户端掉线,TCP服务器很快就会知道。
TCP本身的心跳机制比我们写程序实现的要好了,既可以很快,又不影响正常通信,还无需付费。

如不是的话,则只能商量着来,可以采用如下方法:
1、客户端退出的时候,主要干成0,虽然不能解决所有问题,但至少相对而言准确了。
2、缩短时间间隔,也能相对而言更准确了。
3、干脆由服务器发问询报文,由响应决定在线人数。

你如果用的是TCP协议本身就应该加入心跳机制,服务器定时给客户端发送消息,一但客户端没有回应就判定失去连接关闭socket。我这儿有一个
//主定时器
public void HandleMainTimer(object sender, System.Timers.ElapsedEventArgs e)
{
//处理心跳
HeartBeat();
timer.Start ();
}

public void HeartBeat()
{
    //Console.WriteLine ("[主定时器执行]");
    long timeNow = Sys.GetTimeStamp();

    for (int i = 0; i < conns.Length; i++)
    {
        Conn conn = conns[i];
        if(conn == null)continue;
        if(!conn.isUse) continue;

        if(conn.lastTickTime < timeNow - heartBeatTime)
        {
            Console.WriteLine("[心跳引起断开连接]" + conn.GetAdress());
            lock(conn)
                conn.Close();

        }
    }
}

APP定时发送存活的指令间隔缩短到5分钟(常见心跳间隔时间),5分钟内服务器未再接收到为已下线,APP中指令无法发送时间隔30秒重复发送5次。这个判断的效应,是需要充分考虑多方面因素,假如你可以让APP一直连接服务器,但是手机上运行APP环境是恶劣的,特别是网络环境,手机在移动过程中每经过一个基站范围时就会进行网络切换,此时你的APP就可能中断连接造成误判。而间隔心跳也是为用户手机节省运行资源如省电等等。
最后从统计数据的用途来说,重要的是相对值,一段时间内的每日数据变化体现出业务的变化,才是统计的目的又或说统计学,它们不是需要每个颗粒度一定十分精准。

补充,若你是想要某一时刻的准确在线人数,你可以增加一个动作,在后台统计界面加一个按钮,即可由服务器立即下发一条请求响应指令,APP响应请求即为当前在线。如此可以获得你需要的效果,毕竟前面统计日常在线率才是目的,而当前时刻在线数量只是某些个人爱好的行为不能有什么意义,除了汇报用。