最近在學習go websocket的時候,在學習實驗過程遇到一個比較奇怪問題。為什么我的數據返回是blob,而不是arrayBuffer?百思不得其解。
直到同事打包的時候微信小游戲遇到了一個報錯。FileReader不支持。
經過在社區查詢,官方答復是支持只是arraybuffer /string。那樣在coco creator 調試的時候為什么返回的是blob? 而在微信的開發工作發現返回是Arraybuffer。
1.問題實驗追蹤
在今晚我嘗試做了一個實驗,在結合gpt 交流發現一個問題。首選我們以這樣一個小案例進行實驗。監聽8080的端口,然后返回的時候進行打印。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>webSocket 返回類型問題</title>
</head>
<body>
<script type="text/javascript">const socket = new WebSocket('ws://localhost:8080');socket.onmessage = (event) => {if (event.data instanceof ArrayBuffer) {// 返回ArrayBuffer數據const arrayBuffer = event.data;// 打印二進制數據console.log('接收的二進制數據:', arrayBuffer);}};
</script>
</body>
</html>
在第一次返回的時候,監聽這個數據,返回類型是Blob。的確是Blob類型。
好,進行第二次的設置,修改上述的代碼,加入了一個屬性。 socket.binaryType = “arraybuffer”; 設置返回類型。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>webSocket 返回類型問題</title>
</head>
<body>
<script type="text/javascript">const socket = new WebSocket('ws://localhost:8080');socket.binaryType = "arraybuffer"; //加入binaryType 指定返回類型socket.onmessage = (event) => {if (event.data instanceof ArrayBuffer) {// 返回ArrayBuffer數據const arrayBuffer = event.data;// 打印二進制數據console.log('接收的二進制數據:', arrayBuffer);}};
</script>
</body>
</html>
然后再次查看返回數據結果返回的類型變化了。猜測是只要設置了就能夠返回指定數據。在沒有設置類型的時候,默認是Blob類型。
看似簡單的一個問題,沒有留意就突然不知道怎么解釋。以下為go測試代碼。通過這樣快速檢測數據,則可以指定對應類型返回。
package mainimport ("fmt""github.com/gorilla/websocket""log""net/http"
)var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {return true},
}func main() {http.HandleFunc("/", onMessage)err := http.ListenAndServe(":8080", nil)if err != nil {log.Fatal(err)}
}func onMessage(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {fmt.Println(err)return}defer conn.Close()data := make([]byte, 2)data[0] = 1data[1] = 2//發送 給客戶端err = conn.WriteMessage(websocket.BinaryMessage, data)if err != nil {fmt.Println(err)return}
}
當h5 返回的是Blob的時候應該如何讀取?改造一下讀取方式。采用FileReader的方式進行讀取。這樣就可以滿足到2種類型處理了。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>webSocket 返回類型問題</title>
</head>
<body>
<script type="text/javascript">const socket = new WebSocket('ws://localhost:8080');//socket.binaryType = "arraybuffer"; //加入binaryType 指定返回類型socket.onmessage = (event) => {if (event.data instanceof ArrayBuffer) {// 返回ArrayBuffer數據const arrayBuffer = event.data;// 打印二進制數據console.log('接收的二進制數據:', arrayBuffer);}else if(event.data instanceof Blob){readBlob(event.data)}};function readBlob(blob){const reader = new FileReader();reader.onload = (event) => {// 獲取讀取的結果const result = event.target.result;if (result instanceof ArrayBuffer) {const arrayBuffer = result;// 打印二進制數據console.log('接收的二進制數據:', arrayBuffer);} else {console.error('Failed to read Blob as ArrayBuffer.');}};reader.readAsArrayBuffer(blob);}
</script>
</body>
</html>
同理這樣可以解析到一個問題。數據返回需要設置一下就能返回指定的類型,在沒有指定的時候就默認是Blob。而剛碰見微信小游戲不支持FileReader引發報錯,而微信小游戲返回是直接ArrayBuffer。 這樣就能解釋并非引擎的問題。只是一個屬性參數忘記設置導致的。
好了。今晚實驗到此為止。