如何让C/S应用支持多端(PC、Android、iOS)同时登录?
在C/S架构中,通常是使用 UserID 作为唯一标志来标记每一个用户的,也就是说,对于一个指定的UserID,只能有一个客户端在线。
如果我们开发的系统要支持同帐号多设备同时登录的场景,即需要像微信一样,在PC端登录的同时,也可以使用同一个帐号登录移动端(iOS或Android),那么,如何才能做到了?
解决方案的原理是比较简单的:既然C/S系统要求UserID作为用户标记必须是唯一的,那么我们就引入一个称为“LoginID”的概念,对于同一个用户,在不同类型的设备上就使用不同的LoginID,但是这些LoginID都指向同一个真正的UserID。
一. LoginID 与 UserID
1. 不需要支持同帐号多设备同时登录的简单场景
在之前不支持同帐号多设备同时登录的场景中(简称“单设备登录”场景),登录用的帐号就是真正的UserID,也就是说底层框架中各个API(各个方法以及事件)的参数涉及到的用户帐号都是真正的UserID。比如,一个帐号abc001,该帐号是存在于数据库的用户表中的;使用abc001登录到服务器,在整个的运作过程中,服务端正是使用abc001来标记对应的客户端实例。在该场景中,不会存在多个运行的客户端实例都对应帐号abc001的情况。如果有个客户端已经使用abc001登录,然后再用该帐号在其它地方登录,默认的机制是会把之前登录的那个客户端挤掉线。
2. 需要支持同帐号多设备同时登录的复杂场景
如果现在我们要支持同帐号多设备同时登录的场景(简称“多端登录”场景),那么,服务端在整个的运作过程中,就不能使用abc001来标记对应的客户端实例了,因为存在多个客户端实例都对应同一个abc001帐号的情况。于是,我们使用LoginID来区分这种情况下不同的客户端实例。
常用的方法是,在真正的UserID前加上两个字符的前缀以构成LoginID。 比如,对于abc001这个帐号,在使用iOS设备登录时,我们选择使用前缀“1#”,这样iOS设备使用的LoginID就是1#abc001;同理,Android设备就使用2#abc001。
该两个字符的前缀的含义是这样的:
(1)第二个字符“#”,是一个标志(token),表示该ID是一个LoginID。
(2)第一个字符,表示设备的类型。比如“0”表示.NET设备(PC),“1”表示iOS设备,“2”表示Android设备,等等。
当使用LoginID后,服务端在整个的运作过程中就不再是使用真正的UserID来标记客户端实例了,而是使用LoginID -- 也就是说,框架中各个API(各个方法以及事件)的参数涉及到的用户帐号都是LoginID了。
二. MultiDeviceHelper 类
我写了一个MultiDeviceHelper类,用于为多设备同时登录提供支持。特别是,提供了与LoginID的构造和解析相关的API。
在MultiDeviceHelper的静态构造函数中,规定了每种设备的前缀,如下所示:
static MultiDeviceHelper()
{
#region 如果在当前的应用中,不存在某种类型的设备,则注释掉下面对应的语句即可。
MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.IOS, "1#");
MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.Android, "2#");
MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.DotNet, "3#");
#endregion
}
然后, MultiDeviceHelper提供了多个静态方法以完成真正UserID、设备类型与LoginID之间的转换:

三. 登录和登录验证
客户端在登录时会调用IRapidPassiveEngine的Initialize方法:
LogonResponse Initialize(string userID, string logonPassword, string serverIP, int serverPort, ICustomizeHandler customizeHandler);
该方法的第一个参数就需要传入LoginID,比如 1#abc001。
在服务端会回调IBasicHandler接口的VerifyUser方法来进行帐号密码验证:
bool VerifyUser(string systemToken, string userID, string password, out string failureCause);
此时要注意的是,VerifyUser方法传入的userID参数实际上是LoginID,即 1#abc001。我们需要通过调用MultiDeviceHelper的ParseLoginID方法来获取真正的UserID,该方法会返回 abc001,并且out参数指明设备类型为iOS。
四. 处理消息及其它
服务端是通过回调ICustomizeHandler接口的HandleInformation方法来处理接收到的消息的:
void HandleInformation(string sourceUserID, int informationType, byte[] info);
同上面一样,此处的sourceUserID参数实际上也是LoginID,所以,也需要调用MultiDeviceHelper的ParseLoginID方法来将其转换成真正的UserID。
同理,在多设备登录场景中,框架中各个API(各个方法以及事件)的userID参数实际上都是LoginID,在处理时都需要做类似的处理,这里就不一一列举了。
五. 多设备聊天消息同步
在解决了多设备同时登录的问题后,还有一个常见的需求:类似QQ的PC和手机端同时在线时,别人给我发一条消息,手机端和PC端都能接收到。这样的功能是怎么实现的了?
在单设备登录场景中,我们通常是在客户端调用ICustomizeOutter接口的下列Send方法来发送聊天消息的:
void Send(string targetUserID, int informationType, byte[] info);
该方法的第一个参数是接收者的UserID,表示直接将聊天消息发送给对方(可能是经过服务器中转,或者是经P2P通道直接传送)。
但是,在多设备登录场景中,不能再直接发送了,而是必须要经过服务器中转,通过调用下面的Send方法:
void Send(int informationType, byte[] info);
该Send方法将消息直接发送给服务端,在info参数中包含要消息接收者的UserID。服务端在处理该消息时,需要从info中将接收者UserID解析出来,然后,调用MultiDeviceHelper 的 GetLoginIDList 方法来获取各个设备类型对应的LoginID,然后,服务端在把该消息发送给每一个LoginID。如此,手机端和PC端就都能收到这条聊天消息了。
(注:最新版本的 ESFramework.MSide.dll 已经内置了对多端同时登录的支持,也就是说,本文所阐述的原理已经在ESFramework框架中进行了实现。另外,OrayTalk 也增加了多端登录的功能,可下载测试。)
如何让C/S应用支持多端(PC、Android、iOS)同时登录?的更多相关文章
- Twitter Bootstrap 3.0 正式发布,更好地支持移动端开发
Twitter Bootstrap 3.0 终于正式发布了.这是一个圆滑的,直观的和强大的移动优先的前端框架,用于更快,更容易的 Web 开发.几乎一切都已经被重新设计和重建,更好的支持移动端设备. ...
- vuejs+nodejs支持服务端渲染的博客系统
感悟 历时两个多月,终于利用工作之余完成了这个项目的1.0版本,为什么要写这个项目?其实基于vuejs+nodejs构建的开源博客系统有很多,但是大多数不支持服务端渲染,也不支持动态标题,只是做到了前 ...
- 自己用原生JS写的轮播图,支持移动端触摸滑动,分页器圆点可以支持mouseover鼠标移入和click点击,高手看了勿喷哈
自己用原生JavaScript写的轮播图,分页器圆点按钮可支持click点击,也可支持mouseover鼠标悬浮触发,同时支持移动端触摸滑动,有兴趣的友友可以试试哈,菜鸟一枚,高手看了勿喷,请多多指正 ...
- 自己用原生JS写的轮播图,支持移动端触屏滑动,面向对象思路。分页器圆点支持click和mouseover。
自己用原生javascript写的轮播图,面向对象思路,支持移动端手指触屏滑动.分页器圆点可以选择click点击或mouseover鼠标移入时触发.图片滚动用的setInterval,感觉setInt ...
- jquery photoClip支持手机端,PC端 本地裁剪图片后上传插件
支持手机,PC最好的是jquery photoClip插件,下载地址&示例:https://github.com/topoadmin/photoClip demo.html 代码: <! ...
- pc端和android端应用程序测试有什么区别?(ps面试题)
pc端和android端应用程序测试有什么区别?(ps面试题) [VIP7]大连-凭海临风(215687736) 2014/4/10 8:56:171.测试环境不同PC平台一般都是windows an ...
- Android IOS WebRTC 音视频开发总结(七十)-- 移动端音视频技术优化的七个方向
最近直播很火,很多朋友对背后的技术比较感兴趣,所以今天我们整理一篇关于移动端视频优化的文章,这篇文章是我朋友在一个技术大会上分享过的,更多内容请关注我们的微信公众号:rtcblacker 视频直播为什 ...
- 学习笔记TF066:TensorFlow移动端应用,iOS、Android系统实践
TensorFlow对Android.iOS.树莓派都提供移动端支持. 移动端应用原理.移动端.嵌入式设备应用深度学习方式,一模型运行在云端服务器,向服务器发送请求,接收服务器响应:二在本地运行模型, ...
- SSM整合 完美支持RESTful(Jsp和客户端<android ios...>)
一 RESTful简介 RESTful是一种网络应用程序的设计风格和开发方式 它结构清晰 符合标准 易于理解 扩展方便 REST 即Representational State Transfer的缩写 ...
随机推荐
- python第一课--基础知识
python简介 Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的 ...
- flask项目部署到云服务器+域名绑定
一.效果演示 首页展示 播放页面 该项目部署只为学习,所以用的服务器是腾讯云服务器10元/月,域名也是在腾讯云买的.com 55元/年 因为本人比较穷 哈哈
- java中String,StringBuffer,StringBuilder的区别
String: 1,是字符串常量,一旦创建就不能修改.对于已经存在了的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去. 2,String也是final类,不能被继承. 3,而且S ...
- 数据仓库系列之ETL过程和ETL工具
上周因为在处理很多数据源集成的事情一直没有更新系列文章,在这周后开始规律更新.在维度建模中我们已经了解数据仓库中的维度建模方法以及基本要素,在这篇文章中我们将学习了解数据仓库的ETL过程以及实用的ET ...
- Linux 中如何查询端口被占用的情况
Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000,如下图 可以看到8000端口已经被轻量级文件系统转发服务lwfs ...
- ASP.NET 一个页上需要显示多个验证码
1.后台获取验证字节流,以字符串的形式返回到前端. public ActionResult GetValidateGraphic() { var validate = new ValidateCode ...
- 运行MonkeyRunner时使用Genymotion模拟器
Android自带的模拟器实在太慢太卡,远没有Genymotion的顺畅,所以找了一个办法,在启动py文件时使用Genymotion的模拟器 1.Genymotion安装完成之后,在Settings- ...
- OpenStack Telemetry系统架构及实践
1. 概述 早期OpenStack的计量功能由Ceilometer项目负责,后来Ceilometer一分为四,每个项目负责一个方面的工作.不得不说这是OpenStack开发中的一个特色,比如Cinde ...
- Redis|Sentinel 高可用架构
一 前言 Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端 ...
- 深度学习环境搭建部署(DeepLearning 神经网络)
工作环境 系统:Ubuntu LTS 显卡:GPU NVIDIA驱动:410.93 CUDA:10.0 Python:.x CUDA以及NVIDIA驱动安装,详见https://www.cnblogs ...