2012-10-01 21 views
11

デフォルトのタイムアウトが発生しているかどうかはわかりません(これはどこかに設定できますか?)が、何か不足している可能性があります。クライアントのブラウザがwebsocket接続を確立すると、私は永続性を維持します。次に切断時に、その永続オブジェクトを削除します。十分に簡単です。クライアントがブラウザを閉じるときには通常になりますが、クライアントがWi-Fi接続をオフにしたときにはになりません。(MacBook Proでテストします。 ScalaのコントローラでWebsocketの「ハード」切断が明白ではありませんか?

、私はすべてのinメッセージをログに記録していますが、のWi-Fiをオフにするとが伝わってくるん(私はEOFを期待し、docsから?)。

私は、サーバーがのWebSocket 接続を閉じる必要がありますし、問題をログに記録するWS protocolをどう解釈するかから取られたとして、これは、バグでなければならないと思います。しかし後者は起こりません。

val in = Iteratee.foreach[String](x => { 
    logger.info("Websocket msg: " + x) 
    // expect EOF? 
    x match { 
    case "persist" => // persist some object 
    } 
}).mapDone { x => 
    // delete my persisted object (never happens unless browser/tab closed) 
} 

誰でもこれを体験しましたか?私はシンプルなコントローラと私の設定に合ったものの両方を試しました。下のws3またはws2コントローラーのいずれもこのトリックを行いません。遊びます!以下のコード:

object Application extends Controller { 

    private def ws(out: PushEnumerator[String]) = { 

    Logger.logger.info("ws()") 

    val in = Iteratee.foreach[String](x => { 
     Logger.logger.info("Websocket msg: " + x) 
     try { 
     x match { 
      case "persist" => Logger.logger.info("PERSIST") 
     } 
     } catch { 
     case e: Exception => { 
      Logger.logger.info("NOT RECOGNIZED COMMAND, NO PERSIST") 
     } 
     } 
    }).mapDone { x => 
     Logger.logger.info("STOP PERSIST") 
    } 
    in 
    } 

    def ws2() = WebSocket.using[String] { request => 

    Logger.logger.info("ws2()") 

    val out = Enumerator.imperative[String]() 
    val in = ws(out) 

    (in, out) 
    } 

    def ws3() = WebSocket.using[String] { request => 

    Logger.logger.info("ws3()") 

    val out = Enumerator.imperative[String]() 
    val in = Iteratee.foreach[String](x => { 
     Logger.logger.info("Websocket msg: " + x) 
     try { 
     x match { 
      case "persist" => Logger.logger.info("PERSIST") 
     } 
     } catch { 
     case e: Exception => { 
      Logger.logger.info("NOT RECOGNIZED COMMAND, NO PERSIST") 
     } 
     } 
    }).mapDone { x => 
     Logger.logger.info("STOP PERSIST") 
    } 
    (in, out) 
    } 

    def view() = Action { implicit request => 
    Ok(views.html.index.render("")) 
    } 
} 

ビューは単純です:

@(message: String) @main("Welcome to Play 2.0") { 

@play20.welcome(message) } 

<script type="text/javascript" charset="utf-8"> 
    var sock = new WebSocket("ws://192.168.1.120:9001/ws3"); 

    sock.onopen = function(event) { 
     sock.send('persist'); 
    } 
</script> 

ルート:

GET  /ws2       controllers.Application.ws2 
GET  /ws3       controllers.Application.ws3 
GET  /view       controllers.Application.view 

答えて

2

これは、フレームワークの特定のではなく、ネットワーク関連の問題を再生できません。何が起こるかは、正常に切断すると、他端がFINパケットを送信し、サーバーがハングアップしていることが分かります。もう一方の端にネットワーク接続がない場合は、接続できません。

ソケットが開いているかどうかを確認するにはどうすればよいですか?読み書きしようとすると例外が発生します。しかし、それ自体では起こりませんノンブロッキングモデルです。だからあなたの場合には私が希望:

  • はタイムアウト
  • を持っている(書き込み、何のpingが到着しない場合は、JavaScriptが
  • タイムアウト期間内にpingを送信してください

を抜いたり、サーバー側からのpingを送信ソケットに接続します)。

+0

管理は私が恐れていたものでした。これも見つかりました - https://code.google.com/p/chromium/issues/detail?id=76358 - 。これは、フレームワークに組み込まれたものであるか、少なくとも話されたものでなければならないようです。ありがとう! –

+0

これを読んだ人には、 "socket.io"サーバメモリクリープもこのカテゴリに該当します。 –

関連する問題