LoginSignup
21
14

More than 5 years have passed since last update.

socket.IOにおけるサーバダウン時の再接続イベントの順序

Last updated at Posted at 2018-10-09

サーバが復旧したら自動的に再接続したい

  • イベントたくさんあるんだけど...
    • Event: ‘connect_error’
    • Event: ‘connect_timeout’
    • Event: ‘reconnect’
    • Event: ‘reconnect_attempt’
    • Event: ‘reconnecting’
    • Event: ‘reconnect_error’
    • Event: ‘reconnect_failed’
  • 実は、自動で再接続してくれる
    • これらのエラーハンドラに何も書く必要なし
    • connectイベントに実際の接続処理を書いておくだけで良い
    • io.connect()を呼び出して、socketが割り当てられると、
      • クライアントにはconnect()
      • サーバにはconnection()が発生
    // 先に接続者にIDを割り当てておく
    this.pid    = Math.floor(Math.random()*100)
    this.userID = this.username+"_"+ this.pid
    socket.on("connect", ()=>{
      const msg = [new Date().toRFC2822(), "client", this.username,
                   "[" + this.pid, "user.info]:", "CONN (" + this.target +")", this.host].join(" ")      
      socket.emit("connected", this.username, this.pid, this.target);
    });
    //こんな感じ

せっかく調べたので書き記しておく

イベントの発生順序

  • 最終的に失敗する場合
    1. connect_error
    2. reconnect_attempt
    3. reconnecting
    4. connect_error
    5. reconnect_error
    6. reconnect_attempt
    7. reconnecting
    8. connect_error
    9. reconnect_error
    10. ... 以下2.から5.をreconnectionAttempts回数繰り返し
    11. reconnect_failed
  • 途中で再接続に成功する場合
    1. connect_error
    2. reconnect_attempt ... 1
    3. reconnecting
    4. connect_error
    5. reconnect_error
    6. reconnect_attempt ... 2
    7. reconnecting
    8. reconnect
    9. connect

得られた知見

  • connect_errorとreconnect_errorが一対で出る
    • どういう場合で有用?
  • reconnect_attemptとreconnectingの間の時間はパラメータで指定
    • reconnectionDelay: ミリ秒
  • デフォルトでは、無限に再接続を試みる
    • 有限回でやめたい時はパラメータで指定
    • reconnection: true;
    • reconnectionAttempts: 回数
  • connect_timeoutとの関係は、、、?
    • 誰か調べて
    • タイムアウトまでの間に試行し続けるので永遠にタイムアウトしない様子

クリーンアーキテクチャにおけるチャットクライアント

  • チャットクライアントとControllerは位置付けが同じ
    • View上のイベントをusecaseに中継するのがController
    • サーバ上のイベントをusecaseに中継するのがチャットクライアント
  • チャットサーバは外部インターフェース
    • チャットクライアントはAdapterの一種
    • io.connect()でsocketが割り当て、usecaseを束縛しておくと良いようだ
    • サーバから受け取るイベント、そのイベントハンドラ内でusecaseを呼ぶ
  • 従ってinitializer部で、io.connect()を開始すること
class WebChat {
  constructor(driver){
    this.driver = driver
  }
  open(usecase){
    this.socket = io.connect(this.driver.host, this.driver.opts)
    this.socket.on('connect', function(socket){
       // 接続処理
       usecase.addMessage({value: "CONNECT successfully"})
    })
    return this
  }
}

まとめ

  • socket.IOではサーバダウン時の再接続はデフォルトで有効になっている
    • デフォルトでは無限に(毎秒)再接続を試みるので、それはそれで要注意
  • 再接続を有限回繰り返す場合は、io.connect(host,{
    'reconnection': true,
    'reconnectionDelay': 1000,
    'reconnectionDelayMax' : 5000,
    'reconnectionAttempts': 5
    })

参考情報

21
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
14