2017-12-31 37 views
1

ここで私は非常に興味深い問題があります。私は自分のアプリケーションとDiscord Gatewayの間でwebsocketを介して通信できるように、WebSocketクライアントをLaravel 5.5に統合する方法を見つけようとしていません。私は新しいLaravelアプリをスプールし、Ratchet PHPの上に構築された作曲家経由でこれを要求しました。libraryReactPHP - Laravelとタイマーを使って作業する

私は使用しているが、メジャーdependencyの使用が中止されたこのbotの後にPHP Discord Botを作成しようとしていますが、使用が中止されました。

私は私のアプリは確執からイベントを受信するまで、これは完璧に動作heartbeats

このような
$app->addTimer(x, function ($thing) use ($etc) {}); 

を送信するためにタイマーを追加する方法を考え出しました。同期が失われ、決められた間隔でhello eventという形式でハートビートを送信するのではなく、3〜9秒ごとに送信され、時には2〜3回送信されます。ここではその理由をデバッグするためのコンソールからいくつかの出力があるが、それは私の問題を示しています。ここ

"Sending Heartbeat - 41 - 2017-12-31 05:26:42" 
"Sending Heartbeat - 41 - 2017-12-31 05:26:42" 
Illuminate\Support\Collection {#679 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
Illuminate\Support\Collection {#679 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:26:51" 
Illuminate\Support\Collection {#602 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:26:55" 
Illuminate\Support\Collection {#695 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:26:56" 
Illuminate\Support\Collection {#688 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
Illuminate\Support\Collection {#688 
    #items: array:4 [ 
    "t" => "TYPING_START" 
    "s" => 7 
    "op" => 0 
    "d" => array:3 [ 
     "user_id" => "277968564827324416" 
     "timestamp" => 1514698064 
     "channel_id" => "394991263344230411" 
    ] 
    ] 
} 
Illuminate\Support\Collection {#688 
    #items: array:4 [ 
    "t" => "MESSAGE_CREATE" 
    "s" => 8 
    "op" => 0 
    "d" => array:15 [ 
     "type" => 0 
     "tts" => false 
     "timestamp" => "2017-12-31T05:27:47.057000+00:00" 
     "pinned" => false 
     "nonce" => "396897209817235456" 
     "mentions" => [] 
     "mention_roles" => [] 
     "mention_everyone" => false 
     "id" => "396897202448105494" 
     "embeds" => [] 
     "edited_timestamp" => null 
     "content" => "!about" 
     "channel_id" => "394991263344230411" 
     "author" => array:4 [ 
     "username" => "David Davaham" 
     "id" => "277968564827324416" 
     "discriminator" => "2471" 
     "avatar" => "0c27e1bed49121e8aaf3f284d6b74e55" 
     ] 
     "attachments" => [] 
    ] 
    ] 
} 
Illuminate\Support\Collection {#688 
    #items: array:4 [ 
    "t" => "MESSAGE_CREATE" 
    "s" => 9 
    "op" => 0 
    "d" => array:15 [ 
     "type" => 0 
     "tts" => false 
     "timestamp" => "2017-12-31T05:27:49.382000+00:00" 
     "pinned" => false 
     "nonce" => null 
     "mentions" => array:1 [ 
     0 => array:4 [ 
      "username" => "David Davaham" 
      "id" => "277968564827324416" 
      "discriminator" => "2471" 
      "avatar" => "0c27e1bed49121e8aaf3f284d6b74e55" 
     ] 
     ] 
     "mention_roles" => [] 
     "mention_everyone" => false 
     "id" => "396897212199862276" 
     "embeds" => [] 
     "edited_timestamp" => null 
     "content" => "<@!277968564827324416> Unfortunately That is not a command I recognize. Please try again. Reply with `!help` for a list of commands" 
     "channel_id" => "394991263344230411" 
     "author" => array:5 [ 
     "username" => "Claire Underwood (Dev)" 
     "id" => "394988052360986635" 
     "discriminator" => "8397" 
     "bot" => true 
     "avatar" => null 
     ] 
     "attachments" => [] 
    ] 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:12" 
Illuminate\Support\Collection {#616 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:23" 
"Sending Heartbeat - 41 - 2017-12-31 05:27:23" 
Illuminate\Support\Collection {#622 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
Illuminate\Support\Collection {#622 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:32" 
Illuminate\Support\Collection {#652 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:36" 
Illuminate\Support\Collection {#667 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:37" 
Illuminate\Support\Collection {#661 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:46" 
Illuminate\Support\Collection {#663 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:49" 
Illuminate\Support\Collection {#660 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:51" 
Illuminate\Support\Collection {#656 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:27:53" 
Illuminate\Support\Collection {#698 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:28:04" 
"Sending Heartbeat - 41 - 2017-12-31 05:28:04" 
Illuminate\Support\Collection {#701 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
Illuminate\Support\Collection {#701 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:28:13" 
Illuminate\Support\Collection {#706 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:28:17" 
Illuminate\Support\Collection {#707 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41 - 2017-12-31 05:28:18" 
Illuminate\Support\Collection {#709 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 

は、コードは次のとおりです。

$conn->on('message', function(MessageInterface $msg) use ($conn, $socket, $loop) { 
    $message = collect(json_decode($msg, true)); 
    dump($message); 
    if ($message->has('s') && $message->get('s') !== null) { 
     $this->seq = $message->get('s'); 
    } 
    if (!$this->is_ready) { 
     if (!$message->has('op')) { 
      $conn->close(); 
     } 
     if ($message->get('op') == 0) { 
      if ($message->get('t') === "READY" || $message->get('t') === "GUILD_CREATE") { 
       $this->is_ready = true; 
       $this->seq = $message->get('s'); 
      } 
     } 
     if ($message->get('op') == 10) { 
      $this->connOpened = Carbon::now(); 
      $this->heartbeat = (int)floor($message->get('d')['heartbeat_interval']/1000); 
      $socket->sendIdentify(); 
      sleep(1); 
     } 
     if ($message->get('op') == 11) { 
      $now = Carbon::now()->timestamp; 
      if (!$this->heartbeatACK) { 
       $this->heartbeatACK = true; 
      } 
     } 
    } 
    if ($this->is_ready) { 
     if ($message->get('op') == 0) { 
      if ($message->get('t') === "MESSAGE_CREATE") { 
       $trigger = config('discord.message.trigger'); 
       $data = $message->get('d'); 
       $msgContent = $data['content']; 
       if (starts_with($msgContent, $trigger)) { 
        ProcessMessage::dispatch($data); 
       } 
      } 
     } 
     $now = Carbon::now(); 
     $loop->addTimer($this->heartbeat, function ($x) use ($now, $conn, $socket) { 
      dump("Sending Heartbeat - " . $this->heartbeat . " - " .$now->toDateTimeString()); 
      $payload = collect([ 
       'op' => 1, 
       'd' => (int)$this->seq, 
      ]); 
      $conn->send($payload->toJson()); 
     }); 
    } 

}); 

誰もが道のより良いハートビートを管理するか、これだけである可能性が知っています私は容認する必要がある何か?

また、どのように私はこれをやっているのかアドバイスや批判がありますか?私はどのようにこれを行うには信頼性の高いドキュメントを見つけることができなかったので、私は行くようにそれを一緒に結びつけるのです。

+0

私はこの質問が古いことを知っていますが、あなたはライブラリを使いたいかもしれません。 https://github.com/CharlotteDunois/Yasmin –

答えて

0

これで解決しました。ここで私が見つけたものです:

について概説コードで、次のコードブロックを実行したとき:$this->is_readytrueに設定されていたので、

if (!$this->is_ready) { 
    ... 
    if ($message->get('op') == 0) { 
     if ($message->get('t') === "READY" || $message->get('t') === "GUILD_CREATE") { 
      $this->is_ready = true; 
      $this->seq = $message->get('s'); 
     } 
    } 
    ... 
} 

このスニペットでフォローアップ、それは2つのタイマを引き起こします追加されます。私はこのようなis_readyのコード持っていたので、これに加えて、私は新しいイベントを受信し

if ($this->is_ready) { 
    if ($message->get('op') == 0) { 
     if ($message->get('t') === "MESSAGE_CREATE") { 
      $trigger = config('discord.message.trigger'); 
      $data = $message->get('d'); 
      $msgContent = $data['content']; 
      if (starts_with($msgContent, $trigger)) { 
       ProcessMessage::dispatch($data); 
      } 
     } 
    } 
    $now = Carbon::now(); 
    $loop->addTimer($this->heartbeat, function ($x) use ($now, $conn, $socket) { 
     dump("Sending Heartbeat - " . $this->heartbeat . " - " .$now->toDateTimeString()); 
     $payload = collect([ 
      'op' => 1, 
      'd' => (int)$this->seq, 
     ]); 
     $conn->send($payload->toJson()); 
    }); 
} 

毎回、別のタイマーは、タイマーが積み重ねさせ、予定されていたとハートビートは、とき、それらのタイマー送信します期限切れ。これは、私がこのように残しておけば、1秒間に複数回タイマーが送られる結果に終わりました。

私はこのように、ここで最初のブロックにタイマーを追加しました::以下、私が行った変更がある

if ($message->get('op') == 0) { 
    if ($message->get('t') === "READY" || $message->get('t') === "GUILD_CREATE") { 
     $this->is_ready = true; 
     $loop->addTimer(20, function ($x) use ($conn,$loop) { 
      dump("Sending Heartbeat - " . $this->heartbeat . " - " .Carbon::now()->toDateTimeString()); 
      $payload = collect([ 
       'op' => 1, 
       'd' => (int)$this->seq, 
      ]); 
      $conn->send($payload->toJson()); 
      $loop->cancelTimer($x); 
     }); 
    } 
} 

これはループこのタイマーを処理するための停止を引き起こしますが、一番下に、私はキャンセル私はハートビートを送信した後にタイマーを入れます。 periodicTimerではなく、timerなので、これが重要なのかどうかは分かりませんが、痛いとは思わないです。

次は私がis_readyを再構築する場合は、このような文:opコードは、私が以前heartbeatがされているという事実に頼ってい等しくない0をした場合、私は唯一のタイマーをスケジュールしています

if ($this->is_ready) { 
    if ($message->get('op') == 0) { 
     if ($message->get('t') === "MESSAGE_CREATE") { 
      $trigger = config('discord.message.trigger'); 
      $data = $message->get('d'); 
      $msgContent = $data['content']; 
      if (starts_with($msgContent, $trigger)) { 
       ProcessMessage::dispatch($data); 
      } 
     } 
    } else { 
     $now = Carbon::now(); 
     $loop->addTimer(20, function ($x) use ($conn,$loop) { 
      dump("Sending Heartbeat - " . $this->heartbeat . " - " .Carbon::now()->toDateTimeString()); 
      $payload = collect([ 
       'op' => 1, 
       'd' => (int)$this->seq, 
      ]); 
      $conn->send($payload->toJson()); 
      $loop->cancelTimer($x); 
     }); 
    } 
} 

お知らせスケジュールされ、実行されます。これは、サーバーの起動時に最初のものが実行される限り、ほとんど保証されます。

ここまではコンソールからの出力です。この設定では、ダブルハートビートなどがない状態で約5〜10分間実行されています。

"Sending Heartbeat - 41.25 - 2017-12-31 08:41:18" 
Illuminate\Support\Collection {#702 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:41:38" 
Illuminate\Support\Collection {#704 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:41:58" 
Illuminate\Support\Collection {#706 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:42:18" 
Illuminate\Support\Collection {#708 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:42:39" 
Illuminate\Support\Collection {#710 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
Illuminate\Support\Collection {#712 
    #items: array:4 [ 
    "t" => "PRESENCE_UPDATE" 
    "s" => 7 
    "op" => 0 
    "d" => array:6 [ 
     "user" => array:1 [ 
     "id" => "277968564827324416" 
     ] 
     "status" => "idle" 
     "roles" => [] 
     "nick" => null 
     "guild_id" => "394991263344230409" 
     "game" => null 
    ] 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:42:59" 
Illuminate\Support\Collection {#712 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 
"Sending Heartbeat - 41.25 - 2017-12-31 08:43:19" 
Illuminate\Support\Collection {#717 
    #items: array:4 [ 
    "t" => null 
    "s" => null 
    "op" => 11 
    "d" => null 
    ] 
} 

ご不明な点がございましたら、お気軽にお問い合わせください。このコードは、最終的に私のGithubの公開リポジトリにコミットしてチェックアウトしたい場合に使用します。今のところ、レポはプライベートです。自分のプロフィールで自分のGitHubへのリンクを確認してください。

関連する問題