Vorwort
Dieses Mal zeichnen wir nur die Verwendung von webSocket und Swoole auf, um einen kleinen Chatroom zu erstellen. Die Funktion ist einfach, kann aber als guter Einstiegsfall verwendet werden.
Projekteinführung
Ursprünglich war es als sehr kleiner Fall geschrieben und enthielt nicht so viele Funktionspunkte, daher habe ich mich einfach an die Mindestkonfiguration gehalten.
Ein Chat-Bereich, der Chat-Nachrichten anzeigen kann und dabei auch den Verbindungsstatus berücksichtigt, ob die aktuelle Verbindung erfolgreich ist oder ob die Serververbindung getrennt ist und das Frontend die Situation nicht kennt.
Ein Eingabefeld, ein reines Eingabefeld?
Durch Klicken auf die Schaltfläche „Senden“ wird die Seite nicht aktualisiert, sondern der Inhalt des aktuellen Eingabefelds gelöscht Das Senden wird nicht unterstützt.
Wenn eine Nachricht empfangen wird, berührt die Bildlaufleiste automatisch den unteren Rand. Diese Funktion ist in einigen Nutzungsszenarien praktisch, macht die Verwendung in bestimmten Szenarien jedoch auch unpraktisch. Der Komfort besteht darin, dass kein manueller Bildlauf erforderlich ist Wenn es neue Nachrichten gibt, die Unannehmlichkeit jedoch darin besteht, dass Sie sich möglicherweise historische Nachrichten ansehen und diese automatisch den Tiefpunkt erreicht haben, müssen Sie sie noch entsprechend Ihren tatsächlichen Anforderungen optimieren.
Zufälliger Spitzname, natürlich kein Speichern erforderlich, er geht nach dem Aktualisieren verloren. Wenn Sie die Nachricht erhalten, wird angezeigt, dass [ich] zu diesem oder jenem Zeitpunkt eine bestimmte Nachricht gesendet habe , anstatt die Spitznamenzeichenfolge anzuzeigen.
Projektumgebung
Fügen Sie das kopierte
composer create-project topthink/think tpcd tpcomposer require topthink/think-swooledirekt ein. Da es sich um ein Testprojekt handelt, ist alles standardmäßig installiert. Greifen Sie nach der Installation auf die Frontend-Seite zu und verwenden Sie die Ansichtsmethode, um einen Fehler zu melden. Baidu hat eine Lösung.
WebSocket-Nutzung
Referenzdokumentation:https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
- onopen() initiiert eine Verbindung und wird ausgeführt, nachdem die Verbindung erfolgreich ist .
- onclose() wird ausgeführt, nachdem die Verbindung getrennt wurde.
- onmessage() wird nach dem Empfang der Servernachricht ausgeführt.
- onerror() Der Server wird abnormal ausgeführt.
- Tatsächlich verfügt webSocket über diese gängigen Methoden und stellt keine besonderen Anforderungen. Es existiert als Browser-API, die Verbindungen aufrechterhält und den Serverstatus empfängt.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>打工人聊天室</title> <!--需要引入jq 文件--></head><style> .content { height: 400px; max-width: 400px; overflow: auto; border-radius: 5px; border: 1px solid #f0f0f0; }</style><body> <div id="content" class="content"> <p>聊天区域</p> </div> 你好打工人:<samp id="nickname">昵称</samp> <br> 本次连接FD: <samp id="fd-samp"></samp> <br> <input type="text" id="msg"> <input type="hidden" id="fd" value=""> <button id="send" onclick="send()">发送</button></body></html>JS-Code: Beim Empfang der Serverinformationen gibt es einen Statusunterschied zwischen dem Empfang der ersten Verbindung und dem Empfang der Nachricht durch den Server. Dies kann anhand von msgType unterschieden werden Es handelt sich um die erste Verbindung. Wenn eine Empfangsbestätigung eingeht, wird die FD als Seite gespeichert und nicht im Chat-Nachrichtenbereich angezeigt. Wenn eine Empfangsbestätigung eingeht, wird sie direkt im Chat-Nachrichtenbereich angezeigt. Außerdem sind die von der Front-End- und Back-End-Kommunikation gesendeten Dinge alle von bester String-Natur. Meine Front-End-Verarbeitungsmethode besteht darin, sie zuerst zu einem Objekt zu kombinieren und sie dann in einen JSON-String umzuwandeln.
<script> //滚动条最底部 function scrolltest() { var div = document.getElementById("content"); div.scrollTop = div.scrollHeight; } var wsServer = 'ws://127.0.0.1:9502'; var websocket = new WebSocket(wsServer); var nickname = Math.random().toString(36).substr(2); thisFd = ''; $('#nickname').html(nickname); //点击发送 function send() { var msg = $('#msg').val(); var data = { 'nickname': nickname, 'fd': thisFd, 'data': msg } //生成json 方便后台接收以及使用 var data = JSON.stringify(data); websocket.send(data); //然后清空 $('#msg').val(''); } //链接成功 websocket.onopen = function (evt) { $("#content >p:last-child").after('<p> 服务器已连接,开始聊天吧 </p>'); }; //链接断开 websocket.onclose = function (evt) { $("#content >p:last-child").after('<p> 服务器已断开,请重新连接 </p>'); }; //收到服务器消息 websocket.onmessage = function (evt) { //握手成功后,会接受到服务端返回的fd ,msgType = 1 //字符串格式化成json var data = eval('(' + evt.data + ')'); // console.log(evt.data); switch (data.msgType) { case 1: thisFd = data.fd; $('#fd-samp').html(thisFd); $('#fd').val(thisFd); break; case 2: if (data.nickname == nickname) { data.nickname = '我'; } $("#content >p:last-child").after('<p>' + data.nickname + ' 在 ' + data.time + ' 说:<br>' + data.data + '</p>'); //接收到消息自动触底 scrolltest(); break; } }; //服务器异常 websocket.onerror = function (evt, e) { $("#content >p:last-child").after('<p> 服务器异常 </p>'); };</script>Servercode
Der Server muss die Nachricht vom Frontend zurückrufen, sie in Objektdaten umwandeln, dann einige benutzerdefinierte Daten hinzufügen und sie direkt so zurückgeben, wie sie sind, und sie in großen Mengen an das Frontend senden.
<?php //创建WebSocket Server对象,监听0.0.0.0:9502端口 $ws = new Swoole\WebSocket\Server('0.0.0.0', 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request){ $fd = $request->fd; $data = json_encode([ 'fd' => $request->fd, 'msgType' => 1 //代表第一次连接,前端处理fd ]); $ws->push($request->fd, $data); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { $stats = $ws->stats(); //格式化接收到json $data = json_decode($frame->data); // 原基础上不动,增加一些自定义 $data->msgType = 2; //代表服务器端回复 $data->time = date('Y-m-d H-i-s'); $data = json_encode($data); //因为是聊天室,所以包括自己都需要收到回执,就直接群发 swoole 提供 connections 方法 包含了所有在线的 fd foreach ($ws->connections as $conn_fd){ $ws->push($conn_fd,$data); } }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) {// echo "client-{$fd} is closed\n"; }); $ws->start();Nachdem der Code fertig ist, müssen Sie nur noch die folgende PHP-Datei in der Konsole ausführen.