今天我們繼續來討論協議,今天基本就把一對一聊天的協議定制完畢了,上一篇我們講述了登錄的過程,那么登錄完畢就是聊天了,首先我們還是以A和B為例子,A發送消息給B,那么這條消息的的協議如下
發送消息協議:
{"id":"xxxx","#":"msg","text":"內容","to":"接收用戶ID","type":0,"msgid":"消息ID"
}
id:客戶端生成的ID
#:不說了,我們之前說過,是對應服務器端的Handler
text:消息內容
to:表示發送給誰
type:表示消息類型
msgid:表示消息的ID
肯定有很多人之后看到之后會有一個問題,我們到底需不需要from 也就是說發送者是誰,其實在這里加上也行,但是其實是不需要的,因為如果既然這個人可以發送消息,那么我們可以在這個人對應的回話里邊去存儲這個人的信息,所以說只要發送消息,服務器就知道這條消息來自誰,故不需要在這里加from,然后服務器端要響應給該用戶是否發送成功,返回的協議,我們在上一篇
auth那里講述了,用同一個就好了,那么現在服務器如果發現B在線該去通知B來收消息了,那么我們看一下服務器通知B的協議
服務器通知B的協議:
{"id":"xxxx","#":"psh"}
id:服務器生成的id
#:我們這里用了一個psh表示,通知該用戶你有新的消息,要獲取了,那么B解析到#為psh的時候就應該去請求服務器收消息了 psh=push
B請求服務器收消息協議:
{"id":"xxxx","#":"msg-syn"}
id:客戶端生成ID
#:對應服務器上的某一個Handler
服務器接收到這個json之后,首先會去從回話中找到B的id,然后去redis中查詢聊天信息,多加一句,這里我們存儲redis的時候,key值是我們自己訂制規則添加的,例如如果B的id為1111
那么我定義的key為user:1111:msg,所以獲取消息時候要獲取B的id
獲取完畢之后,那么我們就可以把消息給B了,那么對應的有一個發送消息的協議格式
發送消息協議:
{"id":"xxxx","fr":"發送用戶","text":"內容","time":"消息時間","type":0,"msgid":"消息ID""lv","100"}
id:服務器端生成的id
fr:發送用戶
text:消息內容
time:消息時間
type:消息類型
msgid:消息id
lv:這個不太好理解,這是消息的最大score值,可能很多人對score值不清楚,怎么無緣無故冒出來一個這個東西,我們來解釋一下,比方說A給B發送消息
那么A如果發送了4條消息,對應的存儲應該是:
score value
zset結構: 1 msg1
2 msg2
3 msg3
4 msg4
那么如果用戶B來取消息的時候,我們會找到該系列消息,發送給B,然后B接受成功后,返回json字符串,該字符串 ,包含的內容有,是否接受成功,以及最大消息的score值,該值的作用是如果B接受消息成功,我們要把這些消息從,redis中刪掉,redis提供了一個根據score進行區間刪除的方法我們就可以刪掉0--MAX之間的所有消息了,如果還不明白可以去了解一下redis,如果后續有時間,會把進行數據存儲的代碼貼上來,所以說現在知道我們為什么要獲取最大的值了把。
那么在給B發送消息的時候我們並沒有結束,當把B所有的消息都給B的時候服務器會在最后再發送一條json數據,這里邊包含了是否全部消息都已經發送完畢了,等等信息,如果B接受到該條數據的時候就表示全部收取完畢了,好多朋友會感覺到很不解,為什么最后的這條json里邊會包含了是否消息發送完畢的內容,這里我們做個假設,如果B的人氣非常火,每天有好多好友給他發消息,那么消息數量會很多,所以當B來去消息的時候我們並不會一下子都把消息給B,假設B有1000個消息,我們可能每次就給B100條,然后在這100條后邊加上最后的這個json數據,里邊告訴B是否消息已經全部收取了,B可以根據自己的選擇來選擇是繼續獲取還是不獲取了,主要是做這個使用,那么廢話不多說,我們來看看該條協議的定制
{"id":"57968203","#":"msg-ack","remain":0,"lv":["msg":2]}
id:服務器端生成的id
#:msg-ack這是結束表示符,表示這一次消息已經發送完畢
remain:表示是否還有剩余消息0表示消息全部發送完畢,1表示還有消息未讀
lv:這里邊我們放了一個消息的最大值,其實在這里沒有什么含義,客戶端在返回的時候還是要把這個值返回來的,用數組的原因是后期可能還有很多別的要放在這里邊
客戶端收到消息時候會響應服務器端的,協議如下
客戶端收到消息響應協議:
{"id":"","#" : "msg-fin","lv" : {"msg" : 2}}
id:不說了
#:msg-fin表示獲取消息已經結束了,也就是說B不去獲取消息了,
lv:和上邊是一樣的了,如果實在不懂這個暫時可以忽略掉
那么這么以來一個簡單的一對一聊天的協議我們制定完畢了,其實還有很多細節我沒有去展示,例如心跳機制,還有例如如果B不在線的時候,B如果上線了要主動去獲取一下消息,還有就是檢測用戶是否更換了手機等等細節,這個大體說一下更換手機這方面,更換手機我們依靠的時候用戶手機設備信息然后計算出來一個值,每次去和服務器做對比,這個值什么時候給服務器那,其實在登錄成功之后,隨便找個空閑時間就可以搞定了,也需要定制一個具體的json協議