今天在做自己的WebChat项目(一个多人在线聊天Web端程序)的时候,竟然在最后时刻遇到了一个逻辑问题!看来我的逻辑思考能力仍旧需要锻炼,设计存在一个隐藏的漏洞。
现在,我通过在服务器维护一个在线用户列表和客户端得cookies同时来判断用户是否登录。
问题一:如何确保同一账号只有一个登录?
当cookies失效且服务器端仍旧处于登录状态时,此用户再登陆就会失败,但实际上他是非正常的退出的,比如浏览器关闭等等。这就导致了cookies和服务器数据的不一致。
解决方法一:允许单账户多点登录
实现难度一般,但毕竟系统已经接近完成,且强行修改原代码导致了存在的一些问题。现在按照这种思路能得到的结果是:可以单账户多点登录、但任一登录者退出会导致其他人也退出。
解决方法二:在连接时不同向服务器发送消息,证明登录
实现难度非常大,不仅修改客户端逻辑,更要改服务器端。按照这思路没改成功。
解决方案三:允许强行登录、将原登录者挤下
实现难度也比较大,强行登陆容易做但是将原登录者挤下则不容易。要修改的东西很多,主要是无法标识哪个登录者是原先登录的。
一时未能解决头比较大,但是毕竟完成了第一种解决方案,虽然有些隐藏问题!
之后我分析了WebQQ的判断登录的方法,得出的结果是:WebQQ通过禁止关闭标签页、禁止刷新、禁止关闭浏览器等方法(如果要强行刷新或或关闭标签页则会提示对话框并退出登录),这样确保了页面无故关闭或浏览器关闭导致了cookies失效。但是当机器睡眠时,浏览器进程也休眠也会导致cookies失效,不过qq却能显示出你的连接断开了(题外话:拿Webqq挂qq号是不可取的)。WebQQ也使用了反向AJAX技术使得服务器来调用客户端代码(应该用了DWR或其他现有技术),可以看出因为需要反向AJAX所以它不停的向服务器发送请求,但发送的请求里信息奇怪不知道是否起了证明客户端处于登录的状态。个人认为没有,因为发送信息很简单,而且第二种方案服务器开销较大,即使是腾讯也应该会省钱的。
其次WebQQ多点登录是不可能的,当你的账户从另一个地方登录的时候,原登录者会被挤下,也就是说服务器能确定客户端的状态,并发送信息给客户端。但并不是次次都能挤下去,有的时候就挤不下别人。就算能把别人挤下,原登录者也可以做一些操作,我测试过修改签名可以使用。也就是说登录者每进行一个操作不会次次都验证服务器端是否登录,只验证cookies是否正确。这点实现是和我一下,毕竟次次都验证消耗服务器资源太多。
经过这么比较,决定使用第三种方案,并且需要禁止刷新等等动作,设置cookies直至浏览器关闭才失效,至于将原登录者挤下线就比较困难了。现在正在修改当中!
没有评论:
发表评论