<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      ? ? ? ??在C/S架構(gòu)中,通常是使用 UserID 作為唯一標(biāo)志來(lái)標(biāo)記每一個(gè)用戶的,也就是說(shuō),對(duì)于一個(gè)指定的UserID,只能有一個(gè)客戶端在線。

      ? ? ? ?
      如果我們開(kāi)發(fā)的系統(tǒng)要支持同帳號(hào)多設(shè)備同時(shí)登錄的場(chǎng)景,即需要像微信一樣,在PC端登錄的同時(shí),也可以使用同一個(gè)帳號(hào)登錄移動(dòng)端(iOS或Android),那么,如何才能做到了?

      ? ? ? ?
      解決方案的原理是比較簡(jiǎn)單的:既然C/S系統(tǒng)要求UserID作為用戶標(biāo)記必須是唯一的,那么我們就引入一個(gè)稱為“LoginID”的概念,對(duì)于同一個(gè)用戶,在不同類型的設(shè)備上就使用不同的LoginID,但是這些LoginID都指向同一個(gè)真正的UserID。

      一. LoginID 與 UserID

      1. 不需要支持同帳號(hào)多設(shè)備同時(shí)登錄的簡(jiǎn)單場(chǎng)景

      ??????? 在之前
      不支持同帳號(hào)多設(shè)備同時(shí)登錄的場(chǎng)景中(簡(jiǎn)稱“單設(shè)備登錄”場(chǎng)景),登錄用的帳號(hào)就是真正的UserID,也就是說(shuō)底層框架中各個(gè)API(各個(gè)方法以及事件)的參數(shù)涉及到的用戶帳號(hào)都是真正的UserID。比如,一個(gè)帳號(hào)abc001,該帳號(hào)是存在于數(shù)據(jù)庫(kù)的用戶表中的;使用abc001登錄到服務(wù)器,在整個(gè)的運(yùn)作過(guò)程中,服務(wù)端正是使用abc001來(lái)標(biāo)記對(duì)應(yīng)的客戶端實(shí)例。在該場(chǎng)景中,不會(huì)存在多個(gè)運(yùn)行的客戶端實(shí)例都對(duì)應(yīng)帳號(hào)abc001的情況。如果有個(gè)客戶端已經(jīng)使用abc001登錄,然后再用該帳號(hào)在其它地方登錄,默認(rèn)的機(jī)制是會(huì)把之前登錄的那個(gè)客戶端擠掉線。

      2. 需要支持同帳號(hào)多設(shè)備同時(shí)登錄的復(fù)雜場(chǎng)景

      ?????? 如果現(xiàn)在我們要
      支持同帳號(hào)多設(shè)備同時(shí)登錄的場(chǎng)景(簡(jiǎn)稱“多端登錄”場(chǎng)景),那么,服務(wù)端在整個(gè)的運(yùn)作過(guò)程中,就不能使用abc001來(lái)標(biāo)記對(duì)應(yīng)的客戶端實(shí)例了,因?yàn)榇嬖诙鄠€(gè)客戶端實(shí)例都對(duì)應(yīng)同一個(gè)abc001帳號(hào)的情況。于是,我們使用LoginID來(lái)區(qū)分這種情況下不同的客戶端實(shí)例。

      ?????? 常用的方法是,
      在真正的UserID前加上兩個(gè)字符的前綴以構(gòu)成LoginID。?比如,對(duì)于abc001這個(gè)帳號(hào),在使用iOS設(shè)備登錄時(shí),我們選擇使用前綴“1#”,這樣iOS設(shè)備使用的LoginID就是
      1#abc001;同理,Android設(shè)備就使用2#abc001。

      ??????? 該兩個(gè)字符的前綴的含義是這樣的:

      (1)第二個(gè)字符“#”,是一個(gè)標(biāo)志(token),表示該ID是一個(gè)LoginID。

      (2)第一個(gè)字符,表示設(shè)備的類型。比如“0”表示.NET設(shè)備(PC),“1”表示iOS設(shè)備,“2”表示Android設(shè)備,等等。

      ???????當(dāng)使用LoginID后,服務(wù)端在整個(gè)的運(yùn)作過(guò)程中就不再是使用真正的UserID來(lái)標(biāo)記客戶端實(shí)例了,而是使用LoginID --
      也就是說(shuō),框架中各個(gè)API(各個(gè)方法以及事件)的參數(shù)涉及到的用戶帳號(hào)都是LoginID了。?????

      ???

      二. MultiDeviceHelper 類

      ? ? ? ? 我寫了一個(gè)MultiDeviceHelper類,用于為多設(shè)備同時(shí)登錄提供支持。特別是,提供了與LoginID的構(gòu)造和解析相關(guān)的API。

      ??????? 在MultiDeviceHelper的靜態(tài)構(gòu)造函數(shù)中,規(guī)定了每種設(shè)備的前綴,如下所示:
      static MultiDeviceHelper() { #region 如果在當(dāng)前的應(yīng)用中,不存在某種類型的設(shè)備,則注釋掉下面對(duì)應(yīng)的語(yǔ)句即可。
      MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.IOS, "1#");
      MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.Android, "2#");
      MultiDeviceHelper.LoginIDPrefixMapping.Add(ClientType.DotNet, "3#"); #endregion
      }
      ???????? 然后,?MultiDeviceHelper提供了多個(gè)靜態(tài)方法以完成真正UserID、設(shè)備類型與LoginID之間的轉(zhuǎn)換:

      ???????

      ?

      三. 登錄和登錄驗(yàn)證

      ????? ?客戶端在登錄時(shí)會(huì)調(diào)用IRapidPassiveEngine的Initialize方法:

      ???????LogonResponse?Initialize(string?userID,?string?logonPassword,?string?
      serverIP,?int?serverPort,?ICustomizeHandler?customizeHandler);?

      ?????? 該方法的第一個(gè)參數(shù)就需要傳入LoginID,比如 1#abc001。

      ???????在服務(wù)端會(huì)回調(diào)IBasicHandler接口的VerifyUser方法來(lái)進(jìn)行帳號(hào)密碼驗(yàn)證:

      ????????bool?VerifyUser(string?systemToken,?string?userID,?string?password,
      out?string?failureCause);????????

      ?????? 此時(shí)要注意的是,VerifyUser方法傳入的userID參數(shù)實(shí)際上是LoginID,即
      1#abc001。我們需要通過(guò)調(diào)用MultiDeviceHelper的ParseLoginID方法來(lái)獲取真正的UserID,該方法會(huì)返回
      abc001,并且out參數(shù)指明設(shè)備類型為iOS。

      ?

      四. 處理消息及其它

      ? ? ? ?服務(wù)端是通過(guò)回調(diào)ICustomizeHandler接口的HandleInformation方法來(lái)處理接收到的消息的:

      ?????? void HandleInformation(string?sourceUserID,?int?informationType,?byte[]
      info);?

      ??????
      同上面一樣,此處的sourceUserID參數(shù)實(shí)際上也是LoginID,所以,也需要調(diào)用MultiDeviceHelper的ParseLoginID方法來(lái)將其轉(zhuǎn)換成真正的UserID。

      ??????
      同理,在多設(shè)備登錄場(chǎng)景中,框架中各個(gè)API(各個(gè)方法以及事件)的userID參數(shù)實(shí)際上都是LoginID,在處理時(shí)都需要做類似的處理,這里就不一一列舉了。

      ?

      五. 多設(shè)備聊天消息同步

      ??????
      在解決了多設(shè)備同時(shí)登錄的問(wèn)題后,還有一個(gè)常見(jiàn)的需求:類似QQ的PC和手機(jī)端同時(shí)在線時(shí),別人給我發(fā)一條消息,手機(jī)端和PC端都能接收到。這樣的功能是怎么實(shí)現(xiàn)的了?

      ?????? 在單設(shè)備登錄場(chǎng)景中,我們通常是在客戶端調(diào)用ICustomizeOutter接口的下列Send方法來(lái)發(fā)送聊天消息的:

      ?????? void Send(string?targetUserID,?int?informationType,?byte[] info);?

      ?????? 該方法的第一個(gè)參數(shù)是接收者的UserID,表示直接將聊天消息發(fā)送給對(duì)方(可能是經(jīng)過(guò)服務(wù)器中轉(zhuǎn),或者是經(jīng)P2P通道直接傳送)。

      ?????? 但是,在多設(shè)備登錄場(chǎng)景中,不能再直接發(fā)送了,而是必須要經(jīng)過(guò)服務(wù)器中轉(zhuǎn),通過(guò)調(diào)用下面的Send方法:

      ?????? void Send(int?informationType,?byte[] info);?

      ??????
      該Send方法將消息直接發(fā)送給服務(wù)端,在info參數(shù)中包含要消息接收者的UserID。服務(wù)端在處理該消息時(shí),需要從info中將接收者UserID解析出來(lái),然后,調(diào)用MultiDeviceHelper
      的 GetLoginIDList
      方法來(lái)獲取各個(gè)設(shè)備類型對(duì)應(yīng)的LoginID,然后,服務(wù)端在把該消息發(fā)送給每一個(gè)LoginID。如此,手機(jī)端和PC端就都能收到這條聊天消息了。?

      ?

      (注:最新版本的 ESFramework.MSide.dll 已經(jīng)內(nèi)置了對(duì)多端同時(shí)登錄的支持,也就是說(shuō),本文所闡述的原理已經(jīng)在ESFramework
      <http://www.oraycn.com/ESFramework_detail.aspx>框架中進(jìn)行了實(shí)現(xiàn)。另外,OrayTalk
      也增加了多端登錄的功能,可下載測(cè)試 <http://www.oraycn.com/OrayTalk_download.aspx>。)

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          91一区二区三区四区 | 五月天婷婷网站 | 天天擼夜夜擼狠狠擼 | 亚洲中文字幕第一页 | 国产精品精品久久久久久52AV | 欧美熟妇性又伦-区二区 | 日韩国产欧美一区二区人妻 | 青青青国产免观视频 | 男女男精品视频 | 国产精品久久久免费 |