Workermanを使用したオンラインチャットの実装方法
workerman は、PHP で書かれた通信サービスです。以前のプロジェクトでは、これをデータ インターフェイス サービスとして使用していました。
今回は、シンプルなオンライン チャット ルームを作成するために使用しました~
1. 最新バージョンの workman をダウンロードします。
次のことができます。 http://www.workerman.net ダウンロードに移動
管理を容易にするためにサービスとクライアントを 2 つのフォルダーに分けました
一般的なプロジェクト構造は次のとおりです。
クライアント:
クライアントは単純です。単純な HTML コード。 WebSocket 監視サービスを組み込みました
var ws, name, client_list={}; function connect() { // 创建websocket ws = new WebSocket("ws://192.168.0.88:2345"); // 当socket连接打开时,输入用户名 ws.onopen = onopen; // 当有消息时根据消息类型显示不同信息 ws.onmessage = onmessage; ws.onclose = function() { console.log("连接关闭,定时重连"); connect(); }; ws.onerror = function() { console.log("出现错误"); }; }
WebSocket のオープン、メッセージの監視、クローズを実現します
1. クライアントを開くと、すぐに名前を入力するダイアログ ボックスが表示されます
function onopen(){ //console.log(name); //var username=connect_id=""; if(!name) { name=prompt("请输入您的名字",""); if(!name || name=='null'){ name = '咕哒子'; } } $('#curuser').text(name); data='{"type":"1","user":"'+name+'"}'; ws.send(data); }
を実行し、データをサーバーにプッシュします。 type =1 はログインを表します。
2. メッセージを受信するときは、グループ メッセージかプライベート メッセージか、メッセージの種類を決定します。そして、加工をします。
さらに、新しいユーザーがログインするたびに、ユーザー リストが各クライアントにプッシュされます。レンダリング
function onmessage(e){ //console.log(e.data); var data = eval("("+e.data+")"); var info=$('#chatinfo').html(); if(data.type==1) $('#chatinfo').html(info+'<br/>'+data.data); else if(data.type==2) { // 在线用户列表 userinfo $('#userinfo').html(data.data); } else if(data.type==3) { // 在线用户列表 个人信息 name=data.data.userinfo; //console.log(data.data); } }
次に、各ユーザーがメッセージを送信するためのコードがあります。プライベート チャットでもグループ メッセージでも構いません
$('#send').click(function(e){ var msg=$('#msg').val(); var tofriend=$('#tofriend').val(); var tofriendname=$('#tofriendname').val(); if(tofriend!="") { data='{"type":"3","user":"'+name+'","msg":"'+msg+'","friend_id":"'+tofriend+'","friendname":"'+tofriendname+'"}'; }else{ data='{"type":"2","user":"'+name+'","msg":"'+msg+'"}'; } ws.send(data); $('#msg').attr("value",''); });
クライアントはほぼ次のようなものです。
クライアントにはいくつかの落とし穴があります。
ピット 1。変数名が name の場合、Web ページが更新されてもリセットされません。それ以外の場合はリセットされます。 (情報を確認したところ、name 変数は window.name であることがわかりました。そのため、Web ページを更新しても値は更新されません)
ピット 2. JS グループ配列、変数には " を使用する必要があります。 " で、最外層は '' 例: data='{"type":"1","user":"' name '"}'; そうしないと、解析で問題が発生します。その逆はできません!
サーバー:
サーバーは主にワーカー コンポーネントであり、チャネル分散通信コンポーネントを使用してサブスクリプション、クラスター プッシュ、グループ プッシュ、およびプライベート チャットを実装します。
最初はもちろんモニタリングです。ワーカーの WebSocket モニタリングを有効にします。
// 创建一个Worker监听2346端口,使用websocket协议通讯 $ws_worker = new Worker("websocket://0.0.0.0:2345"); $channel_server = new Channel\Server('0.0.0.0', 2206); // 启动4个进程对外提供服务 $ws_worker->count = 4; $ws_worker->name="kinmoschat";
ワーカーマンのモニタリングが有効になったら、チャネル通信を登録します。
$ws_worker->onWorkerStart=function($ws_worker) { // channel 客户端链接上 服务器 Channel\Client::connect('127.0.0.1',2206); $event_name='私聊'; // 订阅 worker-<id 事件,并注册事件处理函数 Channel\Client::on($event_name,function($event_data)use($ws_worker){ //print_r($event_data); //print_r($ws_worker->connections); $to_connect_id=$event_data['to_connection_id']; $message=$event_data['content']; foreach ($ws_worker->connections as $connection) { if($connection->id==$to_connect_id) { $connection->send($message); } } // if(!isset($ws_worker->connections[$to_connect_id])) // { // echo 'connect is not exist\n'; // return; // } // $to_connection=$ws_worker->connections[$to_connect_id]; // $to_connection->send($message); }); // 订阅广播事件 $event_name = '广播'; // 收到广播 向所有客户端发送消息 Channel\Client::on($event_name,function($event_data)use($ws_worker){ //print_r($event_data); $message=$event_data['content']; foreach ($ws_worker->connections as $connection) { $connection->send($message); } }); };
ブロードキャスト イベント、プライベート チャット イベント、オンライン通知用のブロードキャスト、およびグループ メッセージの 2 つのイベントを登録します。プライベートチャットはプライベートチャットです。 。ここでグループ送信も可能です。ただし、このバージョンはまだ実装されていません。
次に、クライアント リンクのコールバックがあります。
$ws_worker->onConnect=function($connection){ $connection->id = md5($connection->id."_".time()."_".rand(10000,99999)); };
ここでは、クライアントがコールバックするときに、クライアントの connectid を変更します。シンプルな md5 は、主にシリアル ID が簡単に悪用されるのを防ぐことを目的としています。 。
次に、プロジェクト全体の本体、サーバーサイドメッセージの処理コールバックです。
受信クライアントごとに、一意の ID を割り当てます。
connectid=>user を使用して関係テーブルを維持します。
複数のプロセスが開かれているため、セッションに保存されます。 無効, そのため、データベースに保存する予定です。
リンクが切断されたら、データを削除します。
$ws_worker->onMessage = function($connection, $data) { $res=array('code'=>200, 'msg'=>'ok', 'data'=>null,'type'=>1); // 向客户端发送hello $data //print_r($data); $data=json_decode($data,true); //print_r($data); if(!isset($data['type'])||empty($data['type']))// type 1 2 { $res=array('code'=>301, 'msg'=>'消息包格式错误', 'data'=>null); }else{ switch ($data['type']) { case '1': // 客户端上线消息 //print_r($connection->id); if(!isset($data['user'])||empty($data['user'])) { $res=array('code'=>301, 'msg'=>'消息包格式错误', 'data'=>null); break; } // 维护一个数组 保存 用户 connection_id => user $dsn='mysql:host=127.0.0.1;dbname=kinmoschat;'; $pdo=new PDO($dsn,'root','123456'); //准备SQL语句 $sql = "INSERT INTO `user`(`connect_id`,`username`) VALUES (:connect_id,:username)"; //调用prepare方法准备查询 $stmt = $pdo->prepare($sql); //传递一个数组为预处理查询中的命名参数绑定值,并执行SQL $stmt->execute(array(':connect_id' => $connection->id,':username' => $data['user'])); //获取最后一个插入数据的ID值 //echo $pdo->lastInsertId() . '<br />'; // 向自己推送一条消息 $res2['type']=3;// 系统信息 $res2['data']=array('userinfo' =>$data['user']);// 系统信息 $connection->send(json_encode($res2)); $msg="用户 ".$data['user']." 上线了~~"; $res['data']=$msg; break; case '2': // 客户端群发送消息 if(!isset($data['user'])||empty($data['user'])||!isset($data['msg'])||empty($data['msg'])) { $res=array('code'=>301, 'msg'=>'消息包格式错误', 'data'=>null); break; } $msg="用户 ".$data['user']."说:".$data['msg']; $res['data']=$msg; break; case '3': // 客户端私聊 if(!isset($data['user'])||empty($data['user'])||!isset($data['msg'])||empty($data['msg'])||!isset($data['friend_id'])||empty($data['friend_id'])) { $res=array('code'=>301, 'msg'=>'消息包格式错误', 'data'=>null); break; } $msg="用户 ".$data['user']."对您说:".$data['msg']; $res['data']=$msg; $res['type']=1;// 聊天消息 $res1=json_encode($res); // 推送给单个用户 $event_name = '私聊'; Channel\Client::publish($event_name, array( 'content' => $res1, 'to_connection_id' =>$data['friend_id'] )); // 另外还要给自己推条消息 $msg="您对 ".$data['friendname']."说:".$data['msg']; $res['data']=$msg; $res['type']=1;// 聊天消息 $res2=json_encode($res); Channel\Client::publish($event_name, array( 'content' => $res2, 'to_connection_id' =>$connection->id )); return; break; default: # code... break; } } $res['type']=1;// 聊天消息 $res=json_encode($res); // 广播给所有客户端 $event_name = '广播'; Channel\Client::publish($event_name, array( 'content' => $res )); $dsn='mysql:host=127.0.0.1;dbname=kinmoschat;'; $dbh=new PDO($dsn,'root','123456'); $stmt=$dbh->query('SELECT connect_id,username FROM user'); $row=$stmt->fetchAll(); $uerHtml=""; foreach ($row as $key => $value) { $uerHtml.='<a class="user" onclick="userclick(\''.$value['username'].'\',\''.$value['connect_id'].'\');" value="'.$value['connect_id'].'" href="javascript:void(0);">'.$value['username'].'</a><br/>'; } //print_r($row); $res1['type']=2;// 用户消息 $res1['data']=$uerHtml; $res1=json_encode($res1); $event_name = '广播'; Channel\Client::publish($event_name, array( 'content' => $res1 )); };
各ユーザーの connectid=>名前はデータベースに保存されます。 。
オンライン メッセージを受信すると、すべてのユーザーにブロードキャストされます。
グループメッセージを受信しました。 。すべてのクライアントにブロードキャストします。
プライベートメッセージを受け取りました。次に、それを自分と送信者に個別にプッシュします。
クライアント終了イベントをリッスンします。クライアントが終了したら、ユーザー テーブル内の関連レコードを削除します。
// 关闭链接 将数据库中的该数据删除 $ws_worker->onClose=function($connection) { //echo 3233; $dsn='mysql:host=127.0.0.1;dbname=kinmoschat;'; $pdo=new PDO($dsn,'root','123456'); $sql="delete from user where connect_id='".$connection->id."'"; //print_r($sql); $pdo->exec($sql); };
ワーカーマンの詳細については、ワーカーマン チュートリアル#を参照してください。 ## カラム。
以上がWorkermanを使用したオンラインチャットの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Workerman ドキュメントでファイルのアップロードとダウンロードを実装するには、特定のコード サンプルが必要です はじめに: Workerman は、シンプル、効率的、使いやすい高性能 PHP 非同期ネットワーク通信フレームワークです。実際の開発では、ファイルのアップロードとダウンロードが一般的な機能要件となりますが、この記事では、Workerman フレームワークを使用してファイルのアップロードとダウンロードを実装する方法と、具体的なコード例を紹介します。 1. ファイル アップロード: ファイル アップロードとは、ローカル コンピューター上のファイルをサーバーに転送する操作を指します。以下が使用されます

Workerman ドキュメントの基本的な使用方法の実装方法の紹介: Workerman は、開発者が同時実行性の高いネットワーク アプリケーションを簡単に構築できるようにする高性能 PHP 開発フレームワークです。この記事では、インストールと構成、サービスとリスニング ポートの作成、クライアント リクエストの処理など、Workerman の基本的な使用方法を紹介します。そして、対応するコード例を示します。 1. Workerman のインストールと構成 コマンド ラインに次のコマンドを入力して、Workerman をインストールします。

Swoole と Workerman はどちらも高性能の PHP サーバー フレームワークです。 Swoole は、非同期処理、優れたパフォーマンス、スケーラビリティで知られており、多数の同時リクエストと高スループットを処理する必要があるプロジェクトに適しています。 Workerman は、使いやすさや同時実行量が少ないプロジェクトに適した直感的な API を備え、非同期モードと同期モードの両方の柔軟性を提供します。

Workerman 開発: UDP プロトコルに基づくリアルタイム ビデオ通話 概要: この記事では、Workerman フレームワークを使用して、UDP プロトコルに基づくリアルタイム ビデオ通話機能を実装する方法を紹介します。 UDP プロトコルの特性を深く理解し、コード例を通じて、シンプルだが完全なリアルタイム ビデオ通話アプリケーションを構築する方法を示します。はじめに: ネットワーク通信において、リアルタイムのビデオ通話は非常に重要な機能です。従来の TCP プロトコルでは、リアルタイム性の高いビデオ通話を実装する場合、伝送遅延などの問題が発生する可能性があります。そしてUDP

Workerman を使用して高可用性ロード バランシング システムを構築する方法には、特定のコード サンプルが必要です。現代のテクノロジーの分野では、インターネットの急速な発展に伴い、大量の同時リクエストを処理する必要がある Web サイトやアプリケーションがますます増えています。高可用性と高性能を実現するために、負荷分散システムは不可欠なコンポーネントの 1 つになっています。この記事では、PHP オープン ソース フレームワーク Workerman を使用して高可用性負荷分散システムを構築する方法を紹介し、具体的なコード例を示します。 1. ワーカーマンワークの紹介

Workerman ドキュメントにタイマー機能を実装する方法 Workerman は、タイマー機能を含む豊富な機能を提供する強力な PHP 非同期ネットワーク通信フレームワークです。タイマーを使用して、指定された時間間隔内でコードを実行します。これは、スケジュールされたタスクやポーリングなどのアプリケーション シナリオに非常に適しています。次に、Workerman でタイマー機能を実装する方法と具体的なコード例を詳しく紹介します。ステップ 1: Workerman をインストールする まず、Worker をインストールする必要があります

Workerman ドキュメントでリバース プロキシ機能を実装するには、具体的なコード例が必要です はじめに: Workerman は、豊富な機能と強力なパフォーマンスを提供する高性能 PHP マルチプロセス ネットワーク通信フレームワークであり、Web のリアルタイム通信や長時間の通信で広く使用されています。接続、サービス シナリオ。このうち、Workermanはリバースプロキシ機能もサポートしており、サーバーが外部サービスを提供する際の負荷分散や静的リソースのキャッシュを実現できます。この記事ではWorkermanを利用してリバースプロキシ機能を実装する方法を紹介します。

Workerman ドキュメントで TCP/UDP 通信を実装する方法には、特定のコード サンプルが必要です。Workerman は、TCP および UDP 通信の実装に広く使用されている高性能 PHP 非同期イベント ドリブン フレームワークです。この記事では、Workerman を使用して TCP および UDP ベースの通信を実装する方法を紹介し、対応するコード例を示します。 1. TCP 通信用の TCP サーバーを作成します。Workerman を使用して TCP サーバーを作成するのは非常に簡単です。次のコードを記述するだけです: <?ph
