2017-12-31 68 views
1

그래서 여기에 제가 가지고있는 매우 흥미로운 문제가 있습니다. 나는 내 응용 프로그램과 Discord Gateway 사이의 websocket을 통한 통신을 허용하기 위해 websocket 클라이언트를 Laravel 5.5에 통합하는 방법을 알아 내려고 죽었습니다. 새로운 Laravel 앱을 스풀링하여 Ratchet PHP 위에 구축 된 작곡가를 통해 library이 필요합니다.ReactPHP - Laravel 및 타이머 작업

내가 사용하는이 bot 후에 PHP 디스코드 봇을 만들려고 시도 중이지만, 주요 후 dependency 사용이 중단 된 후에 폐기되었습니다.

나는 내 애플 불화에서 이벤트를 수신 할 때까지이 완벽하게 작동이

$app->addTimer(x, function ($thing) use ($etc) {}); 

같은 heartbeats를 보내기 위해에 타이머를 추가하는 방법을 알아 낸. 그런 다음 동기화가 손실되고 결정된 간격 양식 인 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'); 
     } 
    } 
    ... 
} 

이 조각에 의해 다음, 두 개의 타이머를 야기 여기에 내가 뭘 발견이다 첨가되는. 이 외에도, 때문에에게이 같은 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()); 
    }); 
} 

매번는 다른 타이머가 예정되는 때 그 타이머 만료되었습니다. 이로 인해 타이머가 결국 초당 여러 번 전송되는 결과를 낳았습니다.

I는 다음과 같이 여기에 첫 번째 블록에 타이머를 추가 : 다음 내가 만든 변경 사항은

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); 
     }); 
    } 
} 

이 루프이 타이머를 처리 할 수있는 정지가 발생하지만, 하단에, 나는 취소 심장 박동을 보낸 후 타이머. 이것이 단지 timer이고 periodicTimer이 아니기 때문에 이것이 중요한지 나는 잘 모르겠지만 나는 그것이 아플 거라고 생각하지 않는다.

다음 나는 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의 공용 Repo를 확인하려는 경우에 사용됩니다. 당분간, repo는 사적입니다. 내 프로파일에서 내 GitHub에 대한 링크를 확인하십시오.