我正在尝试创建一个全局的websocket-reference,我希望稍后将其扩展为自动重新连接。
但在这里做婴儿步骤我不知道为什么这不能按预期工作:
val uri = s"ws://localhost:1337/websocket"
var websocket: Future[WebSocket] = initWebSocket()
def initWebSocket() : Future[WebSocket] = {
val ws = new WebSocket(uri)
ws.onopen =
{
(event: Event) => log("Websocket connection established")
}
ws.onmessage =
{
(event: MessageEvent) => log("Message received")
}
ws.onclose =
{
// TODO wait some seconds before trying to reconnect
(event: CloseEvent) =>
log("Close event received")
// this.websocket = new WebSocket(uri)
}
Future(ws)
}
我完全清楚(草绘)onclose
的东西现在是绝对的废话!
def main(): Unit = {
websocket.onComplete {
case Failure(x) => println("Epic fail!")
case Success(x) => {
x.send("Test")
}
}
}
我得到的只是
scala.scalajs.js.JavaScriptException:InvalidStateError:尝试使用不可用或不再可用的对象
建立Websocket连接
在加载页面时,与ws:// localhost:1337 / websocket的连接中断。
收到关闭事件
我不甚至想知道为什么!
onopen
被称为太晚了...但如何优雅地解决这个问题?我基本上需要确保在返回websocket之前调用了ws.onopen
。我宁愿不阻止,而是使用一些Promise
或Future
答案 0 :(得分:2)
嗯。看起来你需要在onopen
之后才能解决未来问题。所以我可能会改写这样的东西(记住,我还没有尝试过编译它 - 它可能需要调整):
def initWebSocket() : Future[WebSocket] = {
val promise = Promise[WebSocket]
val ws = new WebSocket(uri)
ws.onopen =
{
(event: Event) => {
log("Websocket connection established")
promise.complete(Success(ws))
}
}
ws.onmessage =
{
(event: MessageEvent) => log("Message received")
}
ws.onclose =
{
// TODO wait some seconds before trying to reconnect
(event: CloseEvent) =>
log("Close event received")
// this.websocket = new WebSocket(uri)
}
promise.future
}
这样,Future就不会立即完成 - 当你希望它完成时,它就会完成,这是在你获得onopen
确认之后。有意义吗?