在學習golang的websocket的時候,出現了這樣錯誤。這個錯誤產生了很大的疑惑。為什麼會出錯?
由於前端作為測試使用,所以編寫乙個較為簡單的測試用例即可。但js裡面的websocket 傳送採取了二進位制去傳送。
ws.binarytype = 『arraybuffer』;
**監聽了本地埠6336
由於是測試,所以直接問人拿了一段測試**。**並不多,只是60行左右。
)//錯誤處理函式
func checkerr(err error, extra string) bool
fmt.fprintf(os.stderr, formatstr, err.error())
return true
} return false
}func svrconnhandler(conn *websocket.conn)
//socket被關閉了
if readlen == 0 else )
t := time.now().unix()
binary.write(outbuff, binary.bigendian, t)
fmt.println("--------", outbuff)
conn.write(outbuff.bytes())
} }}func main()
執行後,出現了websocket斷開的問題。從錯誤可以看到它返回時候把其當成了乙個文字幀處理,所以引起了錯誤。奇怪,明明是二進位制傳送,為何就出現這樣的問題?
websocket connection to 『ws: failed: could not decode a text frame as utf-8.
問題查詢過程,發現了乙個比較奇怪的地方。輸入時間戳會有概率出現問題。同時返回前端解析也出現亂碼的問題。
golang 自帶的websocket 能夠傳送和處理 字串和二進位制。進入了源**裡面可以看到golang封裝的websocket 提供了多種幀,其中文字和二進位制也是常用的。至於其他暫時沒深入了解。但可以從這裡看到textframe和binaryframe兩個較為顯眼的字眼
繼續跟蹤下去,也發現golang 的conn 結構體有乙個對外公開的 設定payloadtype,這個預設情況下為textframe。
type conn struct
問題來了,js前端傳送請求返回是二進位制, ws.binarytype = 『arraybuffer』;然而websocket 返回的乙個文字幀。這樣顯然是不符合的。
於是嘗試設定一下payloadtype。
嘗試將conn.payloadtype = websocket.binaryframe,設定值為binaryframe即是2。
fmt.println("payloadtype:", conn.payloadtype)
conn.payloadtype = websocket.binaryframe
outbuff := bytes.newbuffer(byte{})
t := time.now().unix()
binary.write(outbuff, binary.bigendian, t)
fmt.println("--------", outbuff)
conn.write(outbuff.bytes())
修改完重新再次測試,可以看到返回的了乙個二進位制的格式了。
golang裡面也提供了另外一種方式傳送。這個採用websocket.message.send,通過這個方式我們可以不用關心它是文字幀還是二進位制幀。
websocket.message.send(conn, outbuff.bytes())
fmt.println("payloadtype:", conn.payloadtype)
= websocket.binaryframe
outbuff := bytes.newbuffer(byte{})
t := time.now().unix()
binary.write(outbuff, binary.bigendian, t)
fmt.println("--------", outbuff)
websocket.message.send(conn, outbuff.bytes())
再次跟蹤裡面send方法,從裡面可以猜測到輸入的內容會返回乙個payloadtype,從而不用手動再次去處理。這裡的**會根據的型別從而判斷傳送的型別。
fmt.println("型別", ty) // uint8
8個位元組,int64
經過上面排查,和身邊的朋友也花了很長時間去除錯排查。但也對golang websocket 心感足真的很強大,要理解起來也是花費不少精力。golang絕不是簡單就能掌握到一門語言。
採用下面兩種方式傳送資料報,卻發現不一樣的細節。
1.websocket.message.send(conn, outbuff.bytes())
2.conn.write()
總體來講,還是有一些小收穫。 Go 學習筆記(12) map
map是乙個無序的key value對的集合,其中key是唯一的。如果我們在向字典中放入乙個鍵值對的時候其中已經有相同的鍵的話,那麼與此鍵關聯的那個值會被新值替換。map的字面量是map k t,其中 注意 鍵型別必須是支援 比較運算子的資料型別,否則會引起錯誤。即不能是陣列 切片 字典 結構體 函...
學習筆記12
sql server提供了兩種索引 聚集索引和非聚集索引。其中聚集索引表示表中儲存的資料按照索引的順序儲存,檢索效率比非聚集索引高,但對資料更新影響較大。非聚集索引表示資料儲存 在乙個地方,索引儲存在另乙個地方,索引帶有指標指向資料的儲存位置,非聚集索引檢索效率比聚集索引低,但對資料更新影響較小。聚...
Go學習筆記
使用關鍵字var定義變數,自動初始化為零值。如果提供初始化值,可省略變數型別。在函式內部,可用更簡略的 方式定義變數。空白符號 package main import fmt func test 2,0 函式內部 定義變數陣列data 0 data 1 data 2 並賦值0,1,2,且i 0 i,...