Avant-propos
Cette fois, nous enregistrons uniquement l'utilisation de webSocket et Swoole pour créer une petite salle de discussion. La fonction est simple, mais elle peut être utilisée. comme un bon cas d'entrée.
Introduction au projet
Il a été initialement écrit comme un très petit boîtier, et il n'incluait pas beaucoup de points fonctionnels, j'ai donc simplement suivi la configuration minimale.
Une zone de discussion qui peut afficher les messages de discussion, tout en prenant également en compte l'état du lien, si la connexion en cours est réussie, ou si le serveur est déconnecté, et le front-end ne le fait pas connaître la situation.
Une zone de saisie, une pure zone de saisie ?
Cliquez sur le bouton pour envoyer sans rafraîchir la page, et en même temps effacez le contenu actuel de la zone de saisie, c'est simple. C'est juste un bouton Cliquez pour exécuter. Il ne prend pas en charge la pression sur Entrée pour envoyer.
Lorsqu'un message est reçu, la barre de défilement touche automatiquement le bas. Cette fonction est pratique dans certains scénarios d'utilisation, mais elle la rend également peu pratique à utiliser dans certains scénarios. car il n'y a pas de nouveaux messages. Un défilement manuel est requis. L'inconvénient est que vous regardez peut-être les actualités historiques et qu'elles touchent automatiquement le fond... Vous devez également l'optimiser en fonction de vos besoins réels.
Pseudo aléatoire, bien sûr, pas besoin de sauvegarder, il sera perdu après actualisation. Lors de la réception du message, s'il a été envoyé par moi-même, il affichera [J'ai] envoyé un. certain message à tel ou tel moment, et Au lieu d'afficher la chaîne du pseudo.
Environnement du projet
Collez directement le copié
composer create-project topthink/think tpcd tpcomposer require topthink/think-swoole
Parce qu'il s'agit d'un projet de test, tout est installé par défaut. Après l'installation, lors de l'accès à la page frontale, une erreur sera signalée lors de l'utilisation de la méthode d'affichage. Baidu a une solution en un clic.
Utilisation de webSocket
Documentation de référence : https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
- onopen() initie une connexion et est exécuté une fois la connexion réussie.
- onclose() est exécuté après la déconnexion de la connexion.
- onmessage() est exécuté après réception du message du serveur.
- onerror() Le serveur s'exécute anormalement.
En fait, webSocket n'a que ces méthodes courantes et n'a pas d'exigences particulières. Il existe en tant qu'API de navigateur qui maintient les connexions et reçoit l'état du serveur, ce qui est très simple et pratique.
Code de la page front-end :
<!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>
Code JS :
Lorsque les informations du serveur sont reçues, un premier reçu de connexion ou un reçu de message sera envoyé par le serveur. La différence d'état est distinguée par msgType. S'il s'agit d'un message de réception pour la première connexion, le FD sera enregistré sur une page et ne sera pas affiché dans la zone de message de discussion. sera affiché directement dans la zone de message de chat.
De plus, les éléments envoyés par la communication front-end et back-end entre eux sont tous de la meilleure nature de chaîne. Ma méthode de traitement front-end consiste d'abord à le combiner en un objet, puis à le convertir. dans une chaîne JSON.
<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>
Code du serveur
Le serveur doit rappeler le message depuis le front-end, le convertir en données d'objet, puis ajouter des données personnalisées et le renvoyer directement tel quel, et l'envoyer au front-end en gros.
<?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();
Une fois le code terminé, il vous suffit d'exécuter le fichier PHP suivant dans la console.
Ensuite, la réception accède directement à l'adresse de votre site Web, le mien est le local 127.0.0.1
Ouvrez quelques fenêtres supplémentaires pour simuler plusieurs utilisateurs, Envoyez ensuite un message pour tester :
Bonjour, travailleur.
Le code est très simple et pas difficile, mais il peut refléter la puissance de webScoket et Swoole de manière très concise.