在我的websocket上,我希望从服务器到客户端的二进制消息(另一种方式有效)。我想将其转换为Array[Byte]
以进一步将其处理为protobuf消息
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)
给了我
[对象斑点]
斑点 { 大小: 9, 类型: " }
由于明确的演员表,我希望x
是 ArrayBuffer
型,但唉,事实并非如此,因为我得到
类型错误:数据视图:预期的 ArrayBuffer,获取 Blob
我怎样才能克服这个问题?
我尝试过:
val fr = new FileReader
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
val y = fr.result.asInstanceOf[ArrayBuffer]
dom.window.console.log(y)
但这打印null
y
,也
类型错误:y 不是对象
你快到了: FileReader
是异步的,所以你必须:
val fr = new FileReader
fr.onload = { _ =>
val y = fr.result
dom.window.console.log(y)
}
fr.readAsArrayBuffer(event.data.asInstanceOf[Blob])
这本质上是此响应的翻译示例。
您可能希望在将来的 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 }