2016-05-02 31 views
0

Ich bin ein Anfänger in PHP Websockets und ich versuche, Echtzeit-Chat mit Datenbankspeicher zu erstellen. Mir ging es ziemlich gut, aber jetzt stehe ich bei einem Problem. Es gibt ein Problem, , wenn Benutzer1 Nachricht an Benutzer2 sendet und Benutzer2 zuerst an die Site kam (zuerst auf localhost neu laden), wird es nicht "Echtzeit" sein.PHP Real Time Chat mit Ratchet Websockets

Lassen Sie mich es weiter erklären.

Hier ist meine server.php. Es ist practicly die gleiche wie Ratsche Tutorial:

$loop = React\EventLoop\Factory::create();  
$pusher = new \Pusher(); 
$context = new React\ZMQ\Context($loop); 
$pull = $context->getSocket(ZMQ::SOCKET_PULL); 
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself 
$pull->on('message', array($pusher, 'onBlogEntry')); 
$webSock = new React\Socket\Server($loop); 
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect 
$webServer = new Ratchet\Server\IoServer(
     new Ratchet\Http\HttpServer(
     new Ratchet\WebSocket\WsServer(
     new Ratchet\Wamp\WampServer($pusher))), $webSock); 
$loop->run(); 

In pusher.php wichtigsten sind diese Verfahren (I andere nicht von wichtigen Sachen weggelassen):

protected $subscribedTopics = array(); 
protected $myID = array(); 

public function onSubscribe(ConnectionInterface $conn, $data) { 
    $this->subscribedTopics[json_decode($data)->teamID] = $data; 
    $this->myID[json_decode($data)->userID] = $data;  
} 

public function onBlogEntry($entry) { 
    $entryData = json_decode($entry, true); 

    if ((!array_key_exists($entryData['team_id'], $this->subscribedTopics)) || 
      (!array_key_exists($entryData['to_user_id'], $this->myID)) 
    ) { 
     return; 
    } 

    $teamID = $this->subscribedTopics[$entryData['team_id']]; 
    $teamID->broadcast($entryData); 
} 

In meiner Moderator Klasse Ich habe eine einfache Form. Wenn der Benutzer dieses Formular abschickt, folgt dieser Code:

$this->chatPartner = $values['to_user_id'];  //this I get from the form 
$this->redrawControl('msg');      //here I redraw my layout 
$this->messages_model->addMessage($values);  //here I send data to database 
$context = new \ZMQContext(); 
$socket = $context->getSocket(\ZMQ::SOCKET_PUSH, 'my pusher'); 
$socket->connect("tcp://localhost:5555"); 
$socket->send(json_encode($values)); 

Dann in Ansicht ich diesen JavaScript-Code haben:

var myJSON = '{' 
      + '"teamID" : {$teamId},'  //this I get from the presenter 
      + '"userID" : {$userId}'  //this I get from the presenter 
      + '}'; 
var conn = new ab.Session('ws://localhost:8080', 
     function() { 
      conn.subscribe(myJSON, function(topic, data) { 
      if (data.from_user_id == mypartnerIdA) {      
         //here I edit the DOM 
        } 
       }); 
      }, 
      function() { 
       console.warn('WebSocket connection closed'); 
      }, 
      {'skipSubprotocolCheck': true} 
    ); 

Also, zurück zu meinem Problem. Ich simuliere 2 Benutzer. Benutzer1 lädt diese Seite neu, wobei zuerst die JavaScript-Verbindung hergestellt wird. Benutzer2 lädt diese Seite nach ihm neu. Wenn Benutzer1 eine Nachricht an Benutzer2 sendet, wird die Nachricht sofort (in Echtzeit) angezeigt. Aber wenn Benutzer2 eine Nachricht an Benutzer1 sendet, wird diese Nachricht nicht sofort angezeigt - sie erscheint erst nach dem nächsten Neuladen der Seite.

Und meine Frage ist - Wie man das beheben? Wie kann man die User2-Nachricht auch in Echtzeit erstellen? Wie kann ich diesen Code reparieren?

Antwort

0

Sie haben wahrscheinlich ein Missverständnis darüber, welche Daten Sie abonnieren möchten. Es ist für IDs von Chat-Sitzungen gedacht.

zum Beispiel:

  • A einen Chat mit B (chatId = 1)
  • B einen Chat mit C hat (chatId = 2)
  • C hat einen Chat mit A (chatId = 3)
  • A, B und C sind in einem Chat (chatId = 4)

    var chatId = 2; //this chat is only between users B and C 
    conn.subscribe(chatId , function(topic, data) { 
        ... 
    } 
    

Der einfachste Weg, dies zu verstehen, war der Vergleich mit einem Hashtag auf Twitter. Jeder Hashtag ist in deinem Fall eine ChatId. Und für jedes Abonnement zu einem Hashtag/ChatId. Sie haben eine WebSocket-Verbindung, so dass Sie alle Updates dafür erhalten.

Dies ist eine einfachere Möglichkeit, dies auf lange Sicht zu tun, indem Sie die Verbindungen für einen userId-Parameter unterteilen. Es kann auch leicht in einer Datenbank gespeichert werden, so dass Sie wissen, an wen die Nachrichten gesendet werden sollen und wer nicht.

+0

Mann, vielen Dank, ich habe nicht geglaubt, dass jemand mir hier helfen :)) – mrow

+0

kein Problem, wenn Sie weitere Informationen benötigen, lassen Sie es mich wissen – mitchken