まえがき
今回はwebSocketとSwooleを使って小規模なチャットルームを作成する場合のみ記録します。良いエントリーケースとして。
プロジェクトの紹介
元々は非常に小規模なケースとして書かれており、それほど多くの機能点が含まれていなかったので、最小限の構成に従っただけです。
チャット メッセージを表示できるチャット領域。リンク ステータス、現在の接続が成功したかどうか、サーバーが切断されているかどうか、フロントエンドが切断されているかどうかも考慮されます。状況を知ってください。
入力ボックス、純粋な入力ボックス?
ボタンをクリックしてページを更新せずに送信し、同時に入力ボックスをクリアします。現在の入力ボックスの内容です。これは単純です。単なるボタンです。クリックして実行します。Enter キーを押して送信することはできません。
メッセージを受信するとスクロールバーが自動的に下に下がりますが、この機能は利用シーンによっては便利ですが、利用シーンによっては不便になることもあります。新しいメッセージが利用できないという事実。手動でスクロールする必要がある。不便なのは、おそらく過去のニュースを見ていると、自動的に底をついてしまうことだ。実際のニーズに応じて最適化する必要もある。
ランダムなニックネーム、もちろん保存する必要はありません、更新すると失われます、メッセージを受信すると、自分から送信したものであれば「私」が送信しましたと表示されますニックネームの文字列を表示する代わりに、これこれのときに特定のメッセージを表示します。
プロジェクト環境
コピーしたものを直接貼り付けます
composer create-project topthink/think tpcd tpcomposer require topthink/think-swoole
テストプロジェクトなので、デフォルトですべてがインストールされます。インストール後、フロントエンド ページにアクセスすると、view メソッドを使用するとエラーが報告されますが、Baidu はすぐに解決策を提供します。
webSocket の使用法
参考ドキュメント: https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
- onopen() は接続を開始し、接続が成功した後に実行されます。
- onclose() は、接続が切断された後に実行されます。
- onmessage() は、サーバー メッセージを受信した後に実行されます。
- onerror() サーバーが異常に実行されました。
実は、webSocket はこれらの一般的なメソッドを備えており、特別な要件はなく、接続を維持したりサーバーの状態を受信したりするためのブラウザー API として存在しており、非常にシンプルで便利です。
フロントエンド ページ コード:
<!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 コード:
サーバー情報を受信すると、最初の接続の受信確認、またはサーバーから送信されたメッセージの受信メッセージです。ステータスの違いはmsgTypeで区別されます。初回接続時の受信メッセージの場合、FDはページ上に保存され、チャットメッセージエリアには表示されません。メッセージの場合は、FDはページ上に保存されます。受信通知を受信すると、チャット メッセージ領域に直接表示されます。
また、フロントエンドとバックエンドの通信で送信されるものはすべて最高の文字列の性質を持っており、私のフロントエンドの処理方法は、まずオブジェクトに結合してから、それを 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>
サーバー側コード
サーバーは、フロントエンドからメッセージをコールバックし、それをオブジェクト データに変換し、カスタム データを追加してそのまま直接返し、送信する必要があります。フロントエンドを一括で。
<?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();
コードが完了したら、コンソールで次の PHP ファイルを実行するだけです。
フロント デスクはあなたの Web サイト アドレスに直接アクセスします。私のアドレスはローカル 127.0.0.1
さらにいくつかのウィンドウを開いて複数のユーザーをシミュレートします。次に、テストするメッセージを送信します:
こんにちは、作業員。
コードは非常にシンプルでそれほど難しくありませんが、webScoket と Swoole の機能を非常に簡潔に反映できます。