将 Any/Blob 显式转换为 ArrayBuffer 仍然会给我一个无法处理的 Blob
Explicitly casting Any/Blob to ArrayBuffer still gives me a Blob I can't process
在我的 websocket 上,我期望从服务器到客户端的二进制消息(另一种方式有效)。我想将其转换为 Array[Byte]
以将其进一步处理为 protobuf-message
ws.onmessage = {
(event: MessageEvent) =>
val msg = event.data.toString
dom.window.console.log(msg)
val x = event.data.asInstanceOf[ArrayBuffer]
val df = new DataView(x)
dom.window.console.log("result")
dom.window.console.log(bin2User(df).toString)
}
private def bin2User(data: DataView): User = {
val bytes = new Array[Byte](data.byteLength)
for(index <- 0 to data.byteLength) {
bytes(index) = data.getInt8(index)
}
User.parseFrom(bytes)
}
现在dom.window.console.log(msg)
给我
[object Blob]
Blob { size: 9, type: "" }
我希望 x
是 ArrayBuffer
类型,因为 explicit 强制转换,但遗憾的是,它不是,因为我得到
TypeError: DataView: expected ArrayBuffer, got Blob
我该如何克服这个问题?
我试过:
val fr = new FileReader
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
val y = fr.result.asInstanceOf[ArrayBuffer]
dom.window.console.log(y)
但这会为 y
和
打印 null
TypeError: y is not an object
您快到了:FileReader
是异步的,因此您必须:
val fr = new FileReader
fr.onload = { _ =>
val y = fr.result
dom.window.console.log(y)
}
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
这基本上是来自 this response 的翻译示例。
你以后可能想把它包装起来API:
import scala.concurrent.Promise
def blob2ArrayBuffer(blob: Blob): Future[ArrayBuffer] = {
val result = Promise[ArrayBuffer]()
val fr = new FileReader
fr.onload = { _ => result.success(fr.result) }
fr.readAsArrayBuffer(blob)
result.future
}
正如一些人已经指出的那样,设置 ws.binaryType = "arraybuffer"
也足够了。
这样做:
ws.onmessage =
{
ws.binaryType = "arraybuffer"
(event: MessageEvent) =>
val msg = event.data.asInstanceOf[ArrayBuffer]
dom.window.console.log(msg)
结果
ArrayBuffer { byteLength: 9 }
在我的 websocket 上,我期望从服务器到客户端的二进制消息(另一种方式有效)。我想将其转换为 Array[Byte]
以将其进一步处理为 protobuf-message
ws.onmessage = {
(event: MessageEvent) =>
val msg = event.data.toString
dom.window.console.log(msg)
val x = event.data.asInstanceOf[ArrayBuffer]
val df = new DataView(x)
dom.window.console.log("result")
dom.window.console.log(bin2User(df).toString)
}
private def bin2User(data: DataView): User = {
val bytes = new Array[Byte](data.byteLength)
for(index <- 0 to data.byteLength) {
bytes(index) = data.getInt8(index)
}
User.parseFrom(bytes)
}
现在dom.window.console.log(msg)
给我
[object Blob]
Blob { size: 9, type: "" }
我希望 x
是 ArrayBuffer
类型,因为 explicit 强制转换,但遗憾的是,它不是,因为我得到
TypeError: DataView: expected ArrayBuffer, got Blob
我该如何克服这个问题?
我试过:
val fr = new FileReader
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
val y = fr.result.asInstanceOf[ArrayBuffer]
dom.window.console.log(y)
但这会为 y
和
null
TypeError: y is not an object
您快到了:FileReader
是异步的,因此您必须:
val fr = new FileReader
fr.onload = { _ =>
val y = fr.result
dom.window.console.log(y)
}
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
这基本上是来自 this response 的翻译示例。
你以后可能想把它包装起来API:
import scala.concurrent.Promise
def blob2ArrayBuffer(blob: Blob): Future[ArrayBuffer] = {
val result = Promise[ArrayBuffer]()
val fr = new FileReader
fr.onload = { _ => result.success(fr.result) }
fr.readAsArrayBuffer(blob)
result.future
}
正如一些人已经指出的那样,设置 ws.binaryType = "arraybuffer"
也足够了。
这样做:
ws.onmessage =
{
ws.binaryType = "arraybuffer"
(event: MessageEvent) =>
val msg = event.data.asInstanceOf[ArrayBuffer]
dom.window.console.log(msg)
结果
ArrayBuffer { byteLength: 9 }