如何实现CS应用支持PC、Android、iOS多端同时登录功能?

摘要:在CS架构中,通常是使用 UserID 作为唯一标志来标记每一个用户的,也就是说,对于一个指定的UserID,只能有一个客户端在线。如果我们开发的系统要支持同帐号多设备同时登录的场景,即需要像微信一样,在PC端登录的同时,也可以使用同一个
在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方法: LogonResponseInitialize(stringuserID,stringlogonPassword,stringserverIP,intserverPort,ICustomizeHandlercustomizeHandler); 该方法的第一个参数就需要传入LoginID,比如 1#abc001。
阅读全文