ホームページ >バックエンド開発 >PHPチュートリアル >ユーザーがオンラインかオフラインかの判定について!
最初の要件は、オンライン ユーザーのニックネームとオンライン人数を表示するディスプレイを作成することです。
次に、私の個人的なアイデアは、ユーザーテーブルにフィールドを作成して、ユーザーをオンライン(1)またはオンラインではない(0)としてマークし、ユーザーがログインするときにこのフィールドを1に設定します。チャネル (つまり、セキュリティの終了をクリック) 終了するときは、このフィールドを 0 に設定します。この方法では、オンライン ユーザーを定期的に更新できますが、機能に問題はありませんが、ユーザーが更新する場合が例外です。安全な終了をクリックせずに、直接ブラウジングを終了します。サーバーがインストールされている場合、このユーザーは常にオンラインになるのではないでしょうか?したがって、私の質問は、ユーザーが異常なチャネルを介して離脱した後、オンラインであるかどうかを検出する方法です。
助けてください~~~~
各ページにパブリック js ファイルを追加します。その中の特定の js 関数は、特定の php ファイル (例: a.php) 。最終リクエスト時刻は毎回 a.php によってセッションに書き込まれます
たとえば、2 分ごとにリクエストを送信するように設定します。ユーザーがオンラインかどうかを確認する必要があるページで、セッション内の最後のリクエスト時刻を読み取り、現在の時刻から最後のリクエスト時刻を減算します。その時間が 2 分を超えている場合、ユーザーはオフラインです。
1: 元の投稿者のアイデアはかなり型破りです。おそらく、彼は事前に他の人のアイデアを参照していないと思います。
2: 20 人のユーザーが同時にこのページにアクセスしています。各ユーザーがサーバーにリクエストを送信するのは何回ですか? サーバーが素晴らしいと言いたいのであれば、それには前提条件もあります。ユーザーを馬鹿にして、特定のページに 2 分間滞在させますか?
この問題に関する多くの事例をオンラインで簡単に見つけることができます。 最も軽量な方法を使用したい場合は、一時セッション ファイルの数または他のストレージ方法のユニット数を数えて、現在の 20 分間にオンラインになっているファイルの数を判断できます。もちろん、この時間精度は 1 分にまで低下する可能性があります (セッション リサイクル メカニズムの消費量もそれに伴い増加します)。
どのプランを採用しても、この機能はサーバーに大量のコストを消費しますので、必要ない場合は諦めることをお勧めします。
分析: オンライン統計の難しさは、グローバルな共有方法がないことです
分析方法:
ファイルを使用してオンライン ユーザー情報を保存することで、テキスト処理は実用的です データベースよりもはるかに高速です (PHP がデータベースに接続する時間は、PHP が小さなテキストを読み取る時間を超えています)
テキストに保存される形式は配列であり、形式は
13671927362,//key值为用户uid value值当用户登陆的时间戳 20313=>13671927363,);1: ユーザーがログインすると、現在のタイムスタンプを取得し、セッションがユーザー ID を記録します
2: 次に、オンライン ユーザー情報を保存するファイルをテキストで取得し、現在の uid がここに存在するかどうかを確認し、存在する場合は挿入しますは存在しないため、保存を続行します
3: オンライン ユーザーの数を取得し、そのファイルを読み取り、オンラインの人数をカウントします
4: このファイルにアクセスしている限り (カウントする予定があるかどうかに関係なく)オンラインの人数や新しいユーザーの参加など)、テキスト内のデータを調べて、各ユーザーのタイムスタンプが現在のタイムスタンプより小さいか、30 分を超えているかどうかを確認し、そうである場合は、このユーザー情報を削除します。実装手順:
テキストを配列として取得
$online=require 'xxx.php';
テキストを配列として保存
$data[1111]=123748492 ;
file_put_contents('xx.php','
memcache などのサードパーティツールを使用しない考え方は
分析方法:
オンラインユーザー情報を保存するファイルを利用するため、実際にはテキスト処理が行われますデータベースよりもはるかに高速です (PHP がデータベースに接続する時間は、PHP が小さなテキストを読み取る時間を超えています)
保存されるテキストの形式は配列であり、このファイルにアクセスするときの形式は
PHP code ? 123456 <?php return array( ……
皆さんの返信を読んでも具体的なアイデアがありません
function counter_user_online($temp){ $user_online = "count.txt"; //保存人数的文件,网站根目录下 touch($user_online);//如果没有此文件,则创建 $timeout = 120;//120秒内没动作者,认为掉线 $user_arr = file_get_contents($user_online); $user_arr = explode('#',rtrim($user_arr,'#')); $temp = array(); foreach($user_arr as $value){ $user = explode(",",trim($value)); if (($user[0] != getenv('REMOTE_ADDR')) && ($user[1] > time())) { //如果不是本用户IP并时间没有超时则放入到数组中 array_push($temp,$user[0].",".$user[1]); } } array_push($temp,getenv('REMOTE_ADDR').",".(time() + ($timeout)).'#'); //保存本用户的信息 $user_arr = implode("#",$temp); //写入文件 $fp = fopen($user_online,"w"); flock($fp,LOCK_EX); //flock() 不能在NFS以及其他的一些网络文件系统中正常工作 fputs($fp,$user_arr); flock($fp,LOCK_UN); fclose($fp); echo count($temp);}
引用 4 楼 zouhao619 的回复:正确的思路并且不借助memcache等第三方工具的方法是
分析:在线统计难点是在于不存在全局共享的方法
解析办法:
利用文件来保存在线用户的信息,这样对文本的处理实际上还比数据库快很多(php连数据库的时间就已经超过了php读取一个小文本的时间)
文本里保存的格式为数组,格式为
PHP code ? ……
1:我的是用户访问才触发(你想着,这是渣渣,最好能自动触发.....想一想,用户(包括你自己)想看到在线用户,其实上是已经访问了这个页面了,所以已经触发了这个页面,咳咳,我说的是任何页面都必须有这样的代码,可以参照第5步的方式减少代码冗余)
2:文本里保存的各个的用户以及各个用户操作的时间戳,(如果你觉得这样不好,想更及时一点,也可以选择记录最后一次用户操作页面的时间戳,只是这样会加大服务器的压力,我觉得是没必要的)
3:用户更新时间,实际上我之前说过了.当用户操作页面时,就读取文件,判断用户是否在这个文本里,如果没有就添加当前用户id以及当前用户的时间戳.
4:删除用户时间.当第三步进行的同时,也判断各个用户的时间戳与当前时间戳相差半小时(半小时这个时间可以由你决定最合适的时间)以上的,就删除掉.
5:用户操作每一步都要进行验证判断,读取文本文件,现在一般设计都是采用单入口形式,你可以定义基类,放在构造函数里,这样可以解决代码冗余(每一步都读取文本文件,不要思考压力很大,其实读小文件压力根本不大,当你去访问php页面的时候,实际上也是对这个进行了读操作)
实现流程 我就不讨论了,关于这个存储方法,我倒是建议将数据保存到临时内存表内.当然,这也得考虑你的硬件环境.
这个问题网上可以顺手找到很多案例。
如果想采用最轻巧的,可以统计session临时文件数量或其它存储方式的单元数量,来确定当前20分钟内有多少在线。当然,这个时间精确度可以缩小到一分钟(随之而增长的是会话回收机制的消耗)。
无论采取任何方案,这个功能还是对服务器有不少消耗,如果不是很必要,建议放弃。
我可不可以这样,因为我必须要在数据库里面做一个字段来标志用户是否在线,那么按你这个统计session数量的方法来说,我可以在用户登录的时候用session记录它的id和登录时间,然后设置这个session的过期时间为5个小时,那么我可以每隔20分钟就去遍历一次存放session文件的目录,然后按个儿打开每个session文件,然后分析文件里面的内容获取到用户id和登录时间,然后我把用户的登录时间和当前时间做差如果大于了5个小时(这里是表示限制用户最长能一直在线的时间为5小时)则就把当前id的用户存放在一个数组中,并且删除这个session文件,一直到遍历完所有的文件,将存放过期用户id的数组构造成字符串然后一次性更新数据库。
当然还可能就是用户点击了那个“7天内免登陆”,这样的话我可以在更新之前再加一步,以为我们存cookie的时候用一个固定的前缀和用户id作为名字,那这样我再挨个儿找一遍cookie,将有cookie的id剔除掉,这样的话我就可以很好的实现这个功能了。
那么我也不用在每个页面放一个js文件定时请求服务器了,只需要在哪个显示在线用户的页面里面放一个就可以了。
请问我这种思路有什么问题吗?请指导下,谢谢!
引用 5 楼 BeyondQqiang 的回复:引用 4 楼 zouhao619 的回复:正确的思路并且不借助memcache等第三方工具的方法是
分析:在线统计难点是在于不存在全局共享的方法
解析办法:
利用文件来保存在线用户的信息,这样对文本的处理实际上还比数据库快很多(php连数据库的时间就已经超过了php读取一个小文本的时间)
文本里保存的格式为数组,格式……
请看下9楼我的回复,然后请谈谈你自己的想法,请指教!
实现流程 我就不讨论了,关于这个存储方法,我倒是建议将数据保存到临时内存表内.当然,这也得考虑你的硬件环境.
请看我9楼的回复,请指教!
存入普通文件的关键,是写入时候的资源独占问题。
存入普通文件的关键,是写入时候的资源独占问题。
一语道破
引用 3 楼 dream1206 的回复:这个问题网上可以顺手找到很多案例。
如果想采用最轻巧的,可以统计session临时文件数量或其它存储方式的单元数量,来确定当前20分钟内有多少在线。当然,这个时间精确度可以缩小到一分钟(随之而增长的是会话回收机制的消耗)。
无论采取任何方案,这个功能还是对服务器有不少消耗,如果不是很必要,建议放弃。
我可不可以这样,因为……
不可行!
每次session临时文件是靠sessionId,sessionId不一样,生成临时文件目录都不一样.
我存在的疑问:
1:能够读取临时文件夹的session文件吗?它是否有被加密过?还是纯文本?
2:如果是文本?里面存的就是session的内容?那么那些数组,对象是如何被存入文本的?(数组还可以,对象是怎么存入文本的?)
每次session临时文件是靠sessionId,sessionId不一样,生成临时文件目录都不一样.
我存在的疑问:
1:能够读取临时文件夹的session文件吗?它是否有被加密过?还是纯文本?
2:如果是文本?里面存的就是session的内容?那么那些数组,对象是如何被存入文本的?(数组还可以,对象是怎么存入文本的?)
1、当然可以读取 session 临时文件。你可以在 session.save_path 指定的地方找到他们
2、session 临时文件是纯文本文件。是用简化的序列化格式存储的,php 已然提供了 session 序列化和反序列化的函数。你自己看一下就知道了
你们都在讨论如何存储的问题,其实如何存储并不是主要问题
关键在于“如何识别”,既然一致认为“非正常渠道离开”的检查是需要轮询的。那就把的种方案都弄出来PK一下就是了(假定有一万个用户在线)
引用 3 楼 dream1206 的回复:这个问题网上可以顺手找到很多案例。
如果想采用最轻巧的,可以统计session临时文件数量或其它存储方式的单元数量,来确定当前20分钟内有多少在线。当然,这个时间精确度可以缩小到一分钟(随之而增长的是会话回收机制的消耗)。
无论采取任何方案,这个功能还是对服务器有不少消耗,如果不是很必要,建议放弃。
我可不可以这样,因为……
你不需要去修改你原有的代码,这也是我认为统计session是最轻便的原因。
PHP有GC session机制,它会在一定概率下启动,并清理超过配置项 session.lifetime 的session。这个默认值是21分钟,但是这个误差时间要大,因为不确定在什么时候才能满足概率开始回收过期会话。
你仅仅需要统计session文件夹里有多少个文件而已,不必去一个个的读然后判断。
<?php $path=session_save_path(); $path || ($path='/tmp');$path .= '/sess_*';echo "当前在线人数: ". count( glob($path) );
终极必杀 写一个客户端...想怎么控制怎么控制.
这种CS行为上 BS的网站还是比较吃力,所以如果你对这个场景确实很重视那么就来个客户端吧...
引用 9 楼 BeyondQqiang 的回复:引用 3 楼 dream1206 的回复:这个问题网上可以顺手找到很多案例。
如果想采用最轻巧的,可以统计session临时文件数量或其它存储方式的单元数量,来确定当前20分钟内有多少在线。当然,这个时间精确度可以缩小到一分钟(随之而增长的是会话回收机制的消耗)。
无论采取任何方案,这个功能还是对服务器有不少消耗,如果不……
好吧,你得自己打开一个session文件,然后发现他们其实是可以被手动读出来的并且目录是可以指定的。
回一个,下班了回来看看
都有着弊端