同步協議的設計就是業務契約的設計,本質就是client和server雙方就同步的資訊範圍達成一致。
同乙個事物,存在不同的演化路線。從事物最初狀態開始,不同的演化路線導致同一時間點事物狀態不一樣。給所有不同演化路線上的事物狀態同一時間點確定乙個共同狀態的過程,就叫同步。
im同步是給im使用者進行的資訊同步,同步的事物就是「該im使用者需要知道的所有資訊」。
im同步有兩個基本的特徵:第一是事物共同狀態的確定有且只有乙個標準,那就是server中事物狀態;第二是任何時間點其他client中事物狀態都只能是server中事物狀態的中間狀態。
注:為了降低同步場景的複雜度,client沒有改變本地狀態的許可權,client本地狀態的變化一定是server來主導的。
凡是c/s架構的系統,都可以看作是資訊同步的過程。對於任何需要移動終端和伺服器配合的業務,資訊同步都是業務演進過程中必須要面對的問題。
降低流量。
元資訊,是整個同步協議的基石。沒有元資訊資料,就無法將需要同步的內容描述清楚。任何領域裡面的任何資訊都是由該領域裡面的基本元資訊構成的,資訊本質就是根據元資訊組織規則對元資訊進行組織。
im元資訊是組織im業務的最小資訊單元,由於im資訊組織規則是線性的,im資訊就是im元資訊經過線性組合的結果。
單個屬性
單個關係
單個訊息
群:關係的列表
xx屬性:屬性的列表
好友列表:關係的列表
黑名單列表:關係的列表
單聊會話列表:關係的列表
群聊會話:關係的列表
單聊會話訊息列表:訊息的列表
群組列表:群的列表
群聊會話列表:群聊會話的列表
群聊會話訊息列表:群聊會話的訊息的列表
好友屬性:好友列表中所有好友屬性
同步協議設計包括兩方面:
注:im同步協議中共同狀態已經確定,所以只需要考慮如何把不同client的狀態變成server的狀態。
新增im命令字xx作為協議通道。
① 上行
上行資料也叫同步驅動。同步驅動的意義在於把sdk需要同步的具體資訊告訴server。不管是全量資訊的同步還是部分資訊的同步,都需要明確告訴server需要同步的具體資訊。 1
2
3
4
5
6
7
8
9
request
]
};
② 下行
同步結果。同步結果是元資訊的集合,它明確告訴了sdk需要幹什麼,以及如何去幹。根據元資訊的性質,可以定下規則。凡是靜態屬性(不能被增刪的),一律用值通知;凡是動態屬性(可被增刪的),一律用操作通知。
根據im資訊的構成規則,可以得到同步結果的抽象資料結構是多維列表,這樣就可以明確告訴client更新的資訊及更新的方法。
1
2
3
4
5
6
7
8
9
10
11
response
]
};
client低資訊量、server低計算複雜度和儲存冗餘度兩者之間不能同時滿足。
注:業務契約是同步協議設計的核心內容,定義好業務契約就定義了client和server雙方的業務範圍,也就確定的同步資訊的範圍。
what_do_you_want_to_sync
包括[關係]、[使用者 [屬性] ]兩種im資訊的同步。
對於[關係]:需要返回群成員列表的「變化增量」。
對於[使用者 [屬性] ]:需要返回屬性資訊有變化的群組成員資訊,新增的使用者也算。
在同步群組成員屬性資訊的時候,有可能該群的有些群組成員屬性資訊已經在其他群中被同步了,已經被同步過的成員是否還需要在該群的同步請求中繼續同步?
不需要,那麼完成該業務實際所用到的資訊範圍就和業務描述的資訊範圍不相符了。本來給的資訊只夠描述使用者單個群的,但是實際要求完成的業務卻是要基於使用者整個資訊空間的。
需要,那麼同步僅僅只針對該群的成員屬性資訊,這樣業務同步需要的資訊範圍就和業務描述的資訊範圍一致了。這樣缺點很明顯,那就是該同步範圍可能和其他業務的同步範圍有重疊,造成同步結果的冗餘。
請求描述的資訊範圍和需要同步的資訊範圍一致性(你不能說你要同步a,卻把同步b時需要的資訊告訴我
)、業務和其他業務同步範圍正交性(同步的元資訊盡量做到完全增量)。
凡是改變了sdk本地資料狀態的介面都屬於業務契約,當前能夠改變sdk本地資料狀態的介面如下:
由於im業務本身的特點,業務很難分離成完全正交的子業務,業務與業務之間總會存在著資訊的交集,所以考慮將im整個業務劃分成正交的子業務的想法不可能實現。
但是同步的主要目的是為了降低流量,根據28法則,經常同步的資訊只佔資訊總量的20%,所以能夠將同步的資訊粒度減小才是設計的重中之重。
所以同步契約的對外介面只能保持不變,介面設計上不是正交的。
對有資訊交集的業務做聚類,聚類的結果為業務集,每個業務集之間就是正交的,針對每個業務集做同步就能夠在業務契約設計上實現正交。
每類元資訊的集合當作乙個資訊同步的粒度,此方法能夠實現完全正交。儘管由於同乙個元資訊可能參與了不同業務,並且這些業務之間存在著資訊交集,表面上看起來該類元資訊與其他類元資訊存在著關聯,其實元資訊和元資訊之間是不可能有交集的,有交集的只是業務,不然元資訊就不叫元資訊了。
最典型的場景:獲取群組成員列表,導致屬性的變化和關係的變化會由於業務關聯到一起。
元資訊是關係:
好友列表(同步好友關係的)
群列表(同步群關係的)->
群成員列表(同步群關係的)
群列表(同步群關係的)->群聊會話列表(同步群聊會話的)
單聊會話列表(同步單聊會話的)
元資訊是屬性:
所有的使用者資訊(同步使用者屬性的)
所有的關係資訊(同步關係屬性的)
元資訊是訊息:
單聊會話的訊息(同步單聊訊息的)
群聊會話的訊息(同步群聊訊息的)
致命缺陷:該同步粒度能夠實現同步請求之間同步資訊沒有交集,但是同步資訊的粒度卻是全域性的,每次業務同步請求都需要同步許多不是該請求所要求的資訊。
事件觸發同步適合不需要將變化及時通知到client的情況。
事件通知同步適合client需要將變化盡快同步的情況。
IM 協議選擇 MQTT(mosquitto)
以前大多數im都使用私有協議,後來發展出開放的xmpp,使用xml通訊,不用說消耗網路資源太大了。我本來想使用protobuf自定義一套私有協議,但想到工作量還是太大,然後發現現在mqtt協議很熱門,特別是物聯網使用比較多,不過也可以用來做im訊息推送伺服器。暫時還用不著改mosquitto 直接安...
IM通訊相關協議調研
目前常用的傳輸層協議中有tcp與udp 早期的im因為服務端資源 伺服器硬體 網路頻寬等 比較昂貴且沒有更好的辦法來分擔效能負載,所以很多時候會考慮使用udp,這其中主要是早期的qq為代表。目前基於tcp且可用於即時通訊的應用層協議有http,xmpp,websocket協議。http僅支援客戶端向...
初窺IM通訊協議
s c1 c1每次想和c2通訊,先向s遞乙個申請,然後s同意,把資訊轉交c2,以後每次通訊都這樣 c2s c1 c1第一次想和c2通訊,向s遞乙個申請,s同意,告訴c1,c2,然後 c1和 c2之間建立了一條連線,可以直接通訊,無需經過s.c2第 一種,對伺服器的效能要求比較高,要求伺服器可以同時處...