接続を開いている間、ブラウザからWebSocketサーバーにユーザーIDを送信します

アディブ・アロウイ

この質問をする前に、私はSOに関する厳しい質問を読んで最善を尽くしました(タグ付きのラチェットと同様の問題に対処しましたが、役に立ちませんでした。注目されなかった質問もしたので、別の質問を書くために削除しました(うまくいけばより明確に)。

私の最終的な目標は、ラチェットを使用して1対1のプライベートチャットアプリケーションを構築することです。特定のユーザーにメッセージを送信できないことを除いて、すべてが正常に機能しています。

ログインしたすべてのユーザーは、Webサイトの保護された領域にアクセスしながら、WebSocketサーバーに接続します。

$(document).ready(function() { 

    var conn = new WebSocket('ws://localhost:8080');
        conn.onopen = function(e) {
            console.log("Connection established!");

            // Here I need to send the logged in user_id to websocket server
            // and get it in onOpen method so that I can index my array 
            // of connections with user_id instead of
            //$connection->ResourceId, I explain more below

        };

        conn.onmessage = function(e) {
            console.log(e.data);
        };

});

ユーザーがチャットボックスにメッセージを書き込むと、メッセージはAJAXを介してWebサーバーに送信され、ZeroMQを使用してWebsocketにプッシュされます。コントローラ内:

// Persistence of Message(message_id, sender_id, receiver_id, message_text)
                .....

                $context = new \ZMQContext();
                $socket = $context->getSocket(\ZMQ::SOCKET_PUSH, 'my pusher');
                $socket->connect("tcp://localhost:5555");

                $pushData = array(
                       'receiver_id' => $receiver_id,
                       'sender_id'  => $user->getId(),
                       'message'  => $message->getMessageText(),
                    );
                $socket->send(json_encode($pushData));

したがって、最後に、私のWebSocketサーバーは、JSONを使用して受信者のIDがどれであるかを知ることができます。しかし、彼はどのようにしてそのユーザーの接続がどれであるかを知るのでしょうか?つまり、ユーザーIDでインデックス付けされた配列にWebSocket接続を格納する必要があります。

<?php
namespace RealTime;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;

class Pusher implements WampServerInterface, MessageComponentInterface{

    private $clients;

    public function onOpen(ConnectionInterface $conn) {

        $this->clients[$conn->resourceId] = $conn;
        // I need here to get the user_id received from browser while opening connection
    }

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

        //This is not what I need (It sends to all users in array)
        foreach ($this->clients as $key => $client) {

        $client->send($entryData['message']); 
        }
    }
    public function onMessage(ConnectionInterface $from, $msg) {
        echo $msg; 
    }
}

そして、WebSocketサーバー:

  <?php
        require dirname(__DIR__) . '/vendor/autoload.php';
        use RealTime\Pusher;

        $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'); 
        $pull->on('message', array($pusher, 'onMessageEntry'));


        $webSock = new React\Socket\Server($loop);
        $webSock->listen(8080, '0.0.0.0'); 
        $webServer = new Ratchet\Server\IoServer(
            new Ratchet\Http\HttpServer(
                new Ratchet\WebSocket\WsServer(
                    new Ratchet\Wamp\WampServer(
                        $pusher
                    )
                )
            ),
            $webSock
        );
        $loop->run();

        ?>

質問:

  1. user_id接続を開いているときにクライアント側からログインを送信する方法クライアントの配列に($client[user_id]=$connではなく$client[recourceId]=$connインデックスを付けることができるように、WebSocketサーバーに値を設定する必要がありますjavascript関数を試しましたsendが、送信されたデータをどこで受信するかわかりません(onMessage何も印刷していません)。

  2. onMessageメソッドがMessageComponentInterface実装されていても実行されないのはなぜですかonMessageEntryメソッド+$pull->on('message', array($pusher, 'onMessageEntry'));コード行があるためですか?

ありがとうございました。

アディブ・アロウイ

これは私が見つけたものであり、このソリューションを強化するための提案は大歓迎です。

ラチェットSessionProviderを使用できますこれには、示されているようにSymfonyカスタムセッションハンドラーの1つを使用する必要があります。私は次のコードでを使用しますPdoSessionHandler

<?php
    require dirname(__DIR__) . '/vendor/autoload.php';

    use YourDirectory\Pusher;
    use Symfony\Component\HttpFoundation\Session\Storage\Handler;

    use \Ratchet\Session\SessionProvider;

    $pusher = new Pusher;

    $pdo = new PDO('mysql:host=localhost;dbname=community', 'root', null);

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //This info is related to you db
    $dbOptions = array(
        'db_table'      => 'session',
        'db_id_col'     => 'sess_id',
        'db_data_col'   => 'sess_data',
        'db_time_col'   => 'sess_time',);

        $loop   = \React\EventLoop\Factory::create();
        $context = new \React\ZMQ\Context($loop);
        $pull = $context->getSocket(\ZMQ::SOCKET_PULL);
        $pull->bind('tcp://127.0.0.1:5555');
        $pull->on('message', array($pusher, 'onMessageEntry'));

        $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 SessionProvider(
                        new Ratchet\Wamp\WampServer(
                            $pusher
                        ),new Handler\PdoSessionHandler($pdo,$dbOptions)
                    )
                )
            ),
            $webSock
        );

        $loop->run();
    ?>

次に、私のスタブクラスは次のようになります。

   public function onOpen(ConnectionInterface $conn) {  
        $this->clients[$conn->Session->get('current_user_id')] = $conn;
    }

public function onMessageEntry($entry) {

            $entryData = json_decode($entry, true);
            $ReceiverConnection=$this->clients[$entryData['receiver_id']];
            $ReceiverConnection->send($entryData['message']);                  
        }

ただし、以前は、Webサーバー(最初のページを返すコントローラー内)のセッションにユーザーIDを追加しました。

$user = $this->getUser();
$request->getSession()->set('current_user_id', $user->getId()); 

PS:

  1. PdoSessionHandlerへの移行は、これを実装することで実行できます(Symfony)。

  2. 私はまだ2に答えることができませんが、置くことができるすべてのロジックは、一時的にニーズを満たすonMessageように移動されましonMessageEntryた。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ブラウザがWebSocketでサーバーに接続していません

分類Dev

nodejs wsモジュールをブラウザー化して、ブラウザーがWebSocket接続のサーバー側になるようにすることはできますか

分類Dev

selenium.common.exceptions.WebDriverException:メッセージ:Chromeブラウザを開いている間はサービスchromedriver.exeに接続できません

分類Dev

webSocketを使用して特定の接続ユーザーにメッセージを送信しますか?

分類Dev

Rxを使用して複数のオブザーバーを管理し、サービスへの接続を1つだけ開いたままにする方法は?

分類Dev

共有印刷オブジェクトに接続されているクライアントのサーバーからすべてのIP(またはユーザー名)を取得するにはどうすればよいですか?

分類Dev

DartのブラウザーからWebSocket接続にヘッダーを追加します

分類Dev

エラー以下の取得を停止するには?pythonからChromeブラウザを開いている間

分類Dev

サーバーからブラウザにデータを継続的に送信する方法

分類Dev

ionicアプリが開発サーバーモードになっているかどうかを確認します(ブラウザー)

分類Dev

viewholderフラグメントに活動からユーザーIDを送信しようとしています

分類Dev

ssh経由で接続できるサーバーでWebブラウザを開くにはどうすればよいですか?

分類Dev

ユニバーサルリンクはSafariブラウザの上にバナーを表示しています

分類Dev

iOSにブラウザからのディープ/ユニバーサルリンクを*強制しない*ようにする方法はありますか?

分類Dev

サーバーの再起動時にパスポートを使用して接続ユーザーを保存するにはどうすればよいですか?

分類Dev

ブラウザでxmpp.jsを使用してXMPPサーバーに接続します

分類Dev

サーバーがまだアクティブな状態でブラウザ接続を確認するにはどうすればよいですか?

分類Dev

ブラウザがweblogicサーバーの正しいjsessionIdを送信していませんか?

分類Dev

MCAユーザーIDがMQサーバー接続チャネルを使用してクライアントユーザーIDを承認する方法

分類Dev

ユーザーが接続しているときにlocalStorageからデータを設定する

分類Dev

ユーザーが自分のWebサイトの一部のWebページをブロックして、ブラウザーから直接開くことができないようにするにはどうすればよいですか?

分類Dev

方法:ブラウザはJSONをサーバーに送信しますか?

分類Dev

SFTP SSHユーザーは、同じサーバーに接続している2つのホストから使用します

分類Dev

ユーザー名パスワードを使用してcoreNLPサーバーに接続するにはどうすればよいですか?

分類Dev

MediaRecorderからサーバーにチャンクを送信し、ブラウザーで再生します

分類Dev

HTML5をサポートしていない古いブラウザからWebソケットサーバーにバインドする方法

分類Dev

Javaサーバーはhtmlページをファイルからブラウザに送信します

分類Dev

ファブリック: ユーザーが Twitter に接続しているかどうかを確認する

分類Dev

GUIとブラウザをubuntuサーバーにインストールしてWindows7から接続するにはどうすればよいですか?

Related 関連記事

  1. 1

    ブラウザがWebSocketでサーバーに接続していません

  2. 2

    nodejs wsモジュールをブラウザー化して、ブラウザーがWebSocket接続のサーバー側になるようにすることはできますか

  3. 3

    selenium.common.exceptions.WebDriverException:メッセージ:Chromeブラウザを開いている間はサービスchromedriver.exeに接続できません

  4. 4

    webSocketを使用して特定の接続ユーザーにメッセージを送信しますか?

  5. 5

    Rxを使用して複数のオブザーバーを管理し、サービスへの接続を1つだけ開いたままにする方法は?

  6. 6

    共有印刷オブジェクトに接続されているクライアントのサーバーからすべてのIP(またはユーザー名)を取得するにはどうすればよいですか?

  7. 7

    DartのブラウザーからWebSocket接続にヘッダーを追加します

  8. 8

    エラー以下の取得を停止するには?pythonからChromeブラウザを開いている間

  9. 9

    サーバーからブラウザにデータを継続的に送信する方法

  10. 10

    ionicアプリが開発サーバーモードになっているかどうかを確認します(ブラウザー)

  11. 11

    viewholderフラグメントに活動からユーザーIDを送信しようとしています

  12. 12

    ssh経由で接続できるサーバーでWebブラウザを開くにはどうすればよいですか?

  13. 13

    ユニバーサルリンクはSafariブラウザの上にバナーを表示しています

  14. 14

    iOSにブラウザからのディープ/ユニバーサルリンクを*強制しない*ようにする方法はありますか?

  15. 15

    サーバーの再起動時にパスポートを使用して接続ユーザーを保存するにはどうすればよいですか?

  16. 16

    ブラウザでxmpp.jsを使用してXMPPサーバーに接続します

  17. 17

    サーバーがまだアクティブな状態でブラウザ接続を確認するにはどうすればよいですか?

  18. 18

    ブラウザがweblogicサーバーの正しいjsessionIdを送信していませんか?

  19. 19

    MCAユーザーIDがMQサーバー接続チャネルを使用してクライアントユーザーIDを承認する方法

  20. 20

    ユーザーが接続しているときにlocalStorageからデータを設定する

  21. 21

    ユーザーが自分のWebサイトの一部のWebページをブロックして、ブラウザーから直接開くことができないようにするにはどうすればよいですか?

  22. 22

    方法:ブラウザはJSONをサーバーに送信しますか?

  23. 23

    SFTP SSHユーザーは、同じサーバーに接続している2つのホストから使用します

  24. 24

    ユーザー名パスワードを使用してcoreNLPサーバーに接続するにはどうすればよいですか?

  25. 25

    MediaRecorderからサーバーにチャンクを送信し、ブラウザーで再生します

  26. 26

    HTML5をサポートしていない古いブラウザからWebソケットサーバーにバインドする方法

  27. 27

    Javaサーバーはhtmlページをファイルからブラウザに送信します

  28. 28

    ファブリック: ユーザーが Twitter に接続しているかどうかを確認する

  29. 29

    GUIとブラウザをubuntuサーバーにインストールしてWindows7から接続するにはどうすればよいですか?

ホットタグ

アーカイブ