在游戏开发中,client和server之间需要维护一个心跳 ,用来检测client的网络异常中断(如突然拔掉网线),进而进行一些清理,保存工作.严谨的服务端,除了确保客户端提交的各种请求都合法,此外还需要限制玩家发包速度 ,用来踢掉一些恶意的客户端(如移动加速,攻击重复发包等). 这两个小功能,在Erlang游戏服务器开发中,通过inet:getstat/2可以很容易实现.
首先看看其说明(kernel/inet):
getstat(Socket) getstat(Socket, Options) -> {ok, OptionValues} | {error, posix()}
获取socket的一个或多个统计信息.
getstat(Socket)等同于getstat(Socket, [recv_avg, recv_cnt, recv_dvi, recv_max, recv_oct, send_avg, send_cnt, send_dvi, send_max, send_oct])(注意在R14B02中这里有一个笔误,send_dvi应该为send_pend).
选项说明:
通过间隔的判断recv_cnt,我们可以得知client是否还在"活动",我们不需要处理专门的"心跳"数据包.通过socket的统计信息便可.
通过定期(或随机)的检测recv_cnt, recv_oct,我们可以得知某个client,是否在一段时间内频繁发送数据,是否发送了大量的数据,
从而做一些应对.
下面是在Erlang shell中的调用举例:
> inet:getstat(Socket). {ok,[{recv_oct,38832}, {recv_cnt,106}, {recv_max,1460}, {recv_avg,366}, {recv_dvi,33}, {send_oct,9896}, {send_cnt,104}, {send_max,574}, {send_avg,95}, {send_pend,0}]} > inet:getstat(Socket,[recv_cnt, recv_oct]). {ok,[{recv_cnt,114},{recv_oct,41175}]}
注意:inet:getstat/2的返回值,不要匹配错误 :)