今天來說說Skynet客戶端和服務端網絡通信的基礎部分。
Skynet當前版本。lua是skynet自帶的5.3版本。
根據示例,我們可以知道。通信的步驟如下。
-
客戶端按大小端打包成二進制。
-
socket發送。
-
服務端接收。
-
服務端解包。
逐個說說這其中的操作方法。1.第一步
local result = string.pack(">s2","string2pack")
pack > 表示按大端順序。s2 表示按照2個字節打包。我們知道string由char組成。1個char 是 0-255 之間的數,2^8 ,1char=8byte. 1byte=1位0/1.
需要注意的是,他除了被打包的部分之外,還會在前面加2個字節,表示長度。
如果要打包一個數字則需要轉換。由2種辦法
string.pack("I2",number),會在前面二進制加2位表示長度的東西。
2.第二步
socket.send
3.服務端接收
gateserver已經有接收的代碼了。
注意的是,socket會自動按pack的數據分段接收。也就是會根據pack的前面2位得到size。根據size去接收后面的數據。然后向上傳遞一份message。
接收到的message已經是去掉了前面2位的數據。
4.客戶端接收
客戶端接收到的數據目前我是用skynet提供的“client.socket”.沒有netpack可用。
接收到的數據需要自行去除前面的2個字節的數據(string.pack產生的)。
這樣算是完成了基礎版本的通信。以上的實驗可以通過在服務端和客戶端最終發出和最初的接收的地方加校驗碼做測試。【參考這2個鏈接打印二進制】
但是這樣是不夠的。我們還需要找一套協議,比如sprotol。本來說sprotol就夠了。但是一般來說,各種通信協議,都是分為控制校驗和數據層兩塊。
比如示例中就加多了一個數據大小和session的設計。sprotol不用說簡單易用,區分好客戶端和服務端加載的順序即可。
至於控制層依據個人習慣,一般來說,開頭的地方拼接二進制就行。session還是有點用的,如果同一個客戶端對同一個session多次發送
,可以在session級別做緩沖,減輕服務器壓力,具體代碼可以參見示例。也可以加標志位,作為是否加密等等。校驗碼,用來在gate層過濾垃圾消息。
但是其實這些都可以做到sprotol中去,作為一個公共的字段,但是沒見sprotol支持這種寫法。可以上述方法或者直接在sprotol中加字段實現。
但是在sprotol中加字段,將暴露給上層應用,不太符合網絡協議設計的分層控制的思想,總之需要對sprotol做一些改動才行。