最近在学习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 main
import (
"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] = 1
data[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。 这样就能解释并非引擎的问题。只是一个属性参数忘记设置导致的。
好了。今晚实验到此为止。