Scala.js全球WebSocket - > InvalidStateError

时间:2017-05-02 20:53:09

标签: scala asynchronous websocket promise scala.js

我正在尝试创建一个全局的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。我宁愿不阻止,而是使用一些PromiseFuture

1 个答案:

答案 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确认之后。有意义吗?