Der WebSocket-Room von Think-Swoole tritt dem Raum bei, verlässt ihn und sendet Raumnachrichten

Freigeben: 2020-10-21 17:17:35
nach vorne
2896 Leute haben es durchsucht

Der WebSocket-Room von Think-Swoole tritt dem Raum bei, verlässt ihn und sendet Raumnachrichten

Think-Swoole 3.0 fügt Websocket die Room-Chatroom-Funktion hinzu, die hauptsächlich für Gruppennachrichten verwendet wird, aber Nachrichten zwischen verschiedenen Räumen sind voneinander isoliert. Wenn wir einen Chatraum betreten, kann nur der FD dieses Chatraums die Nachrichten empfangen, die wir betreten, verlassen und senden.

config.swoole.php

'websocket'  => [
        'enable'        => true,
        'handler'       => Handler::class,
        'parser'        => Parser::class,
        'ping_interval' => 25000,
        'ping_timeout'  => 60000,
        'room'          => [
            'type'  => 'table',
            'table' => [
                'room_rows'   => 4096,
                'room_size'   => 2048,
                'client_rows' => 8192,
                'client_size' => 2048,
            ],
            'redis' => [
                'host'          => '127.0.0.1',
                'port'          => 6379,
                'max_active'    => 3,
                'max_wait_time' => 5,
            ],
        ],
        'listen'        => [],
        'subscribe'     => [],
    ],
Nach dem Login kopieren

Es gibt ein Raumkonfigurationselement und der darin enthaltene Typ gibt an, welche Datenverarbeitungsmethode verwendet wird. Es gibt zwei Typen, „Tabelle“ und „Redis“, die direkt verwendet werden können erfordert die Installation der Redis-Erweiterung in unserem System und Projekt. table ist ein leistungsstarker, prozessübergreifender Speicherverarbeitungsdienst, der Daten zwischen verschiedenen Prozessen austauschen kann.

Ereignisse erstellen

Geben Sie die folgenden Befehle in das Stammverzeichnis des Projekts ein, um Ereignisse zum Betreten des Raums, Ereignisse zum Verlassen des Raums bzw. zum Chatten im Raum zu erstellen:

php think make:listener WsJoin
php think make:listener WsLeave
php think make:listener RoomTest
Nach dem Login kopieren

Dann definieren Sie Ereignisse in app/event.php:

[
    ],
    'listen'    => [
        'AppInit'  => [],
        'HttpRun'  => [],
        'HttpEnd'  => [],
        'LogLevel' => [],
        'LogWrite' => [],
        //监听连接,swoole 事件必须以 swoole 开头
        'swoole.websocket.Connect' => [
            app\listener\WsConnect::class
        ],
        //监听关闭
        'swoole.websocket.Close' => [
            \app\listener\WsClose::class
        ],
        //监听 Test 场景
        'swoole.websocket.Test' => [
            \app\listener\WsTest::class
        ],
        //加入房间事件
        'swoole.websocket.Join' => [
            \app\listener\WsJoin::class
        ],
        //离开房间事件
        'swoole.websocket.Leave' => [
            \app\listener\WsLeave::class
        ],
        //处理聊天室消息
        'swoole.websocket.RoomTest' => [
            \app\listener\RoomTest::class
        ],
    ],
    'subscribe' => [
    ],
];
Nach dem Login kopieren

wie oben Namen wie „Join“, „Leave“ und „RoomTest“ werden alle angepasst und müssen dem Szenenwert der vom Front-End gesendeten Nachricht entsprechen.

Natürlich kann die Ereignisdefinition auch im Websocket-Listen der Konfigurationsdatei config/swoole.php konfiguriert werden. Weitere Informationen finden Sie im vorherigen Artikel.

H5 WebSocker-Client-Verbindung

wsroot.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button onclick="join()">加入房间</button>
<button onclick="leave()">离开房间</button>
<input type="text" id="message">
<button onclick="send()">发送</button>
<script>
    var ws = new WebSocket("ws://127.0.0.1:9501/?uid=1");
    ws.onopen = function(){
        console.log(&#39;连接成功&#39;);
    }
    //数据返回的解析
    function mycallback(data){
        var start = data.indexOf(&#39;[&#39;) // 第一次出现的位置
        var start1 = data.indexOf(&#39;{&#39;)
        if(start < 0){
            start = start1;
        }
        if(start >= 0 && start1 >= 0){
            start = Math.min(start,start1);
        }
        if(start >= 0){
            console.log(data);
            var json = data.substr(start); //截取
            var json = JSON.parse(json);
            console.log(json);
            // if(json instanceof Array){
            //     window[json[0]](json[1]);
            // }
        }
    }
    function sendfd($message){
        console.log($message)
    }
    function testcallback($message){
        console.log($message)
    }
    function joincallback($message){
        // console.log($message)
        console.log(11);
    }
    function leavecallback($message){
        console.log($message)
    }
    ws.onmessage = function(data){
        // console.log(data.data);
        mycallback(data.data);
    }
    ws.onclose = function(){
        console.log(&#39;连接断开&#39;);
    }
    function join()
{
        var room = prompt(&#39;请输入房间号&#39;);
        ws.send(JSON.stringify([&#39;join&#39;,{
            room:room
        }])); //发送的数据必须是 [&#39;test&#39;,数据] 这种格式
    }
    function leave()
{
        var room = prompt(&#39;请输入要离开的房间号&#39;);
        ws.send(JSON.stringify([&#39;leave&#39;,{
            room:room
        }])); //发送的数据必须是 [&#39;test&#39;,数据] 这种格式
    }
    function send()
{
        var message = document.getElementById(&#39;message&#39;).value;
        var room = prompt(&#39;请输入接收消息的房间号&#39;)
        ws.send(JSON.stringify([&#39;RoomTest&#39;,{
            message:message,
            room:room
        }])); //发送的数据必须是 [&#39;test&#39;,数据] 这种格式
    }
</script>
</body>
</html>
Nach dem Login kopieren

SocketIO-Client-Verbindung

ioroomtest.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button onclick="join()">加入房间</button>
<button onclick="leave()">离开房间</button>
<input type="text" id="message">
<button onclick="send()">发送</button>
<script src="./socketio.js"></script>
<script>
    //http 协议
    var socket = io("http://127.0.0.1:9501?uid=1", {transports: [&#39;websocket&#39;]});
    socket.on(&#39;connect&#39;, function(){
        console.log(&#39;connect success&#39;);
    });
    socket.on(&#39;close&#39;,function(){
       console.log(&#39;connect close&#39;)
    });
    //send_fd 为自定义的场景值,和后端对应
    socket.on("sendfd", function (data) {
        console.log(data)
    });
    //testcallback 为自定义的场景值,和后端对应
    socket.on("testcallback", function (data) {
        console.log(data)
    });
    socket.on("joincallback", function (data) {
        console.log(data)
    });
    socket.on("roomtestcallback", function (data) {
        console.log(data)
    });
    function join()
{
        var room = prompt(&#39;请输入房间号&#39;);
        socket.emit(&#39;join&#39;,{
            room : room
        });
    }
    function leave()
{
        var room = prompt(&#39;请输入要离开的房间号&#39;);
        socket.emit(&#39;leave&#39;,{
            room : room
        });
    }
    function send()
{
        var message = document.getElementById(&#39;message&#39;).value;
        var room = prompt(&#39;请输入接收消息的房间号&#39;)
        socket.emit(&#39;RoomTest&#39;,{
            message : message,
            room : room
        });
    }
</script>
</body>
</html>
Nach dem Login kopieren

Seiten-, Join()-, Leave()- und Send()-Funktionen Die definierten Szenenwerte sind Join, Leave und RoomTest. Wir haben die Ereignisse, die diesen Szenenwerten entsprechen, in app/leave.php definiert, sodass die Ereignisse WsJoin.php, WsLeave.php und RoomTest.php jeweils ausgelöst werden.

Schreiben von Back-End-Ereignissen

app/listener/WsJoin.php

<?php
declare (strict_types = 1);
namespace app\listener;
class WsJoin
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event)
{
        $ws = app(&#39;think\swoole\Websocket&#39;);
        $roomobj = app(&#39;think\swoole\websocket\Room&#39;);
        //当前客户端加入指定 Room
        $ws -> join($event[&#39;room&#39;]);
        //同时加入多个房间
//        $ws -> join([&#39;room1&#39;,&#39;room2&#39;]);
        //指定客户端加入指定 room
//        $ws -> setSender(2) -> join($event[&#39;room&#39;]);
        //获取当前房间所有的 fd
        $getAllFdInRoom = $roomobj -> getClients($event[&#39;room&#39;]);
        //获取指定 fd 加入哪些房间
        $getAllRoom = $roomobj -> getRooms($ws -> getSender());
        var_dump(&#39;当前房间所有 fd:&#39;,$getAllFdInRoom);
        var_dump(&#39;当前 fd 加入的所有房间:&#39;,$getAllRoom);
        var_dump(&#39;当前请求数据:&#39;,$event);
        $ws -> emit(&#39;joincallback&#39;,&#39;房间加入成功&#39;);
    }
}
Nach dem Login kopieren

app/listener/WsLeave.php

<?php
declare (strict_types = 1);
namespace app\listener;
class WsLeave
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event)
{
        $ws = app(&#39;think\swoole\Websocket&#39;);
        $roomobj = app(&#39;think\swoole\websocket\Room&#39;);
        // 当前客户端离开指定 room
        $ws -> leave($event[&#39;room&#39;]);
        // 同时离开多个 room
//        $ws -> leave([&#39;one&#39;,&#39;two&#39;]);
        // 指定客户端离开指定 room
//        $ws -> setSender(2) -> leave($event[&#39;room&#39;]);
        // 获取指定 room 中的所有客户端 fd
        $getAllFdInRoom = $roomobj -> getClients($event[&#39;room&#39;]);
        var_dump(&#39;当前房间还剩 fd:&#39;,$getAllFdInRoom);
        $ws -> emit(&#39;leavecallback&#39;,&#39;房间离开成功&#39;);
    }
}
Nach dem Login kopieren

app/listener/RoomTest.php

<?php
declare (strict_types = 1);
namespace app\listener;
class RoomTest
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event)
{
        var_dump($event);
        $ws = app(&#39;think\swoole\Websocket&#39;);
        //给指定的 room 内所有 fd 发送消息,包括当前客户端,当前客户端没有加入该 room 也可发送
        $ws -> to($event[&#39;room&#39;]) -> emit(&#39;roomtestcallback&#39;,$event[&#39;message&#39;]);
        //指定多个 room 发送消息
        //$ws -> to([&#39;one&#39;,&#39;two&#39;]) -> emit(&#39;客户端场景值&#39;,$event[&#39;message&#39;]);
    }
}
Nach dem Login kopieren

Die oben genannten sind die Front-End-HTML-Seiten und die Back-End-Ergänzungen Room, hinterlassen Sie den Room- und Room-Chat-Ereigniscode und beginnen Sie unten mit dem Testen.

Aktivieren Sie zunächst den Think-Swoole-Dienst im Projektstammverzeichnis.

Besuchen Sie die Seite wsroot.html oder ioroomtest.html. Sie können mehrere Registerkarten öffnen und zunächst drei Clients öffnen 1 und Clients von 2 treten alle dem Raum „eins“ bei, und Clients mit fd von 3 treten dem Raum „zwei“ bei, da wir im WsJoin.php-Event „Raum beitreten“ alle FDS des Benutzers ausdrucken, der dem Raum beitritt Räume, denen der Benutzername beigetreten ist, werden diese Informationen in der Befehlszeile gedruckt und schließlich werden der aktuelle Client-Chat-Szenenwert und die Informationen „Dem Raum erfolgreich beitreten“ an den Client gesendet, die in der Browserkonsole angezeigt werden können.

Nachdem Sie dem Raum beigetreten sind, verwenden Sie den Client mit fd = 1, um die zu sendende Nachricht in das Eingabefeld der Seite einzugeben. Nachdem Sie auf „Senden“ geklickt haben, geben Sie den Namen des zu sendenden Raums als „eins“ ein und dann den Die Nachricht wird an den „einen“ Raum gesendet. Nur alle Clients im „einen“ Raum (fd ist 1 und 2) können die Nachricht empfangen.

Lassen Sie nun den Client mit fd 2 den Raum „eins“ verlassen. Da wir im WsLeave.php-Event den verbleibenden fd nach dem Verlassen ausdrucken, werden in der Befehlszeile nur die Informationen angezeigt „ein“ Raum ist übrig, fd 1 sendet Informationen, fd 2 kann sie nicht empfangen.

Weitere Funktionen von WebSocket-Room wurden im obigen Code kommentiert und müssen zum Testen geöffnet werden.

H5 WebSocket und SocketIO haben die Verarbeitung von Nachrichten bereits im vorherigen Artikel demonstriert. Ersteres erfordert eine manuelle Analyse der vom Server zurückgegebenen Nachricht, bevor sie verwendet werden kann, während letzteres die Nachricht entsprechend dem Szenenwert empfängt Nachricht und verarbeiten Sie sie, bevor Sie sie direkt verwenden.

Das obige ist der detaillierte Inhalt vonDer WebSocket-Room von Think-Swoole tritt dem Raum bei, verlässt ihn und sendet Raumnachrichten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:阿dai哥
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!