2017-05-02 49 views
0

我想創建一個全球websocket參考,我想稍後擴展到自動重新連接。Scala.js全球WebSocket - > InvalidStateError

但是在這裏做嬰兒的步驟我不知道這是爲什麼不工作按預期:

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: An attempt was made to use an object that is not, or is no longer, usable

Websocket connection established

The connection to ws://localhost:1337/websocket was interrupted while the page was loading.

Close event received

而且我甚至不知道爲什麼!

onopen被稱爲太遲......但如何優雅地解決這個問題?我基本上需要確保在返回websocket之前調用ws.onopen。我寧願不要阻止,而是使用一些PromiseFuture

回答

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 
} 

這樣一來,未來不立即完成 - 當它完成要求它這樣做,這是在你得到onopen確認後。合理?

+0

完美無缺,謝謝! – Sorona