ThinkPHP5.1框架与Workerman之GatewayWorker框架结合案例
GatewayWorker是基于Workerman开发的一个可分布式部署的TCP长连接框架,专门用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等
文档地址:http://www.workerman.net/gatewaydoc/
一、测试官方DEMO(Windows 版本)
1、下载demo(在下方评论中自取)
2、解压到任意位置,我这里为:
D:\phpStudy\PHPTutorial\WWW\GatewayWorker
3、进入GatewayWorker目录
4、双击start_for_win.bat启动。(如果出现错误请参考这里设置php环境变量),效果如下
5、命令行窗口运行 telnet 127.0.0.1 8282,输入任意字符即可聊天(非本机测试请将127.0.0.1替换成实际ip)。
PS:以上表示TCP连接测试成功
二、修改测试websocket
1、需要修改 start_gateway.php 指定websocket协议,像这样
$gateway = new Gateway(websocket://0.0.0.0:7272);
2、重新启动 start_for_win.bat
3、测试js
小结:只需要改动一个文件( start_gateway.php)的协议和端口即可,别的不需用改动。
三、与ThinkPHP5.1框架结合
(一)服务端主动推送消息到客户端
原则:
1、TP5.1框架项目与GatewayWorker独立部署互不干扰
2、所有的业务逻辑都由网站(websocket连接的)页面以post/get请求到TP5.1框架的控制器中完成
3、GatewayWorker不接受客户端发来的数据,即GatewayWorker不处理任何业务逻辑,GatewayWorker仅仅当做一个单向的推送通道
4、仅当TP5.1框架需要向浏览器主动推送数据时才在TP5.1框架中调用Gateway的API(GatewayClient)完成推送
具体实现步骤
1、网站页面建立与GatewayWorker的websocket连接
ws = new WebSocket("ws://127.0.0.1:7272");
2、GatewayWorker发现有页面发起连接时,将对应连接的client_id发给网站页面
Event.php 内容
public static function onConnect($client_id) { $resData = [ 'type' => 'init', 'client_id' => $client_id, 'msg' => 'connect is success' // 初始化房间信息 ]; Gateway::sendToClient($client_id, json_encode($resData)); }
index.html 内容
GatewayWorker的websocket连接 GatewayWorker的websocket连接
3、网站页面收到client_id后触发一个ajax请求(index/chat_room/bind)将client_id发到TP5.0后端,bind方法
/* * 用户登录后初始化以及绑定client_id */ public function bind() { // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值 Gateway::$registerAddress = '127.0.0.1:1238'; $uid = $this->userId; $group_id = $this->groupId; $client_id = request()->param('client_id'); // client_id与uid绑定 Gateway::bindUid($client_id, $uid); // 加入某个群组(可调用多次加入多个群组) Gateway::joinGroup($client_id, $group_id); }
4、后端收到client_id后利用GatewayClient调用Gateway::bindUid($client_id, $uid)将client_id与当前uid(用户id或者客户端唯一标识)绑定。如果有群组、群发功能,也可以利用Gateway::joinGroup($client_id, $group_id)将client_id加入到对应分组
连接成功后返回值
PS:以上返回值为 GatewayWorker服务 连接成功后返回的json数据
5、页面发起的所有请求都直接post/get到mvc框架统一处理,包括发送消息
通过sendMessage发送消息(服务端主动推送消息到客户端)
// mvc后端发消息 利用GatewayClient发送 Events.php public function sendMessage() { // stream_socket_client(): unable to connect to tcp://127.0.0.1:1236 $uid = $this->userId; $group = $this->groupId; $message = json_encode([ 'type'=>'say', 'msg'=>'Hello ThinkPHP5' ]); // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值 Gateway::$registerAddress = '127.0.0.1:1238'; // 向任意uid的网站页面发送数据 Gateway::sendToUid($uid, $message); // 向任意群组的网站页面发送数据,如果开启,则会向页面发送两条一样的消息 //Gateway::sendToGroup($group, $message); }
6、mvc框架处理业务过程中需要向某个uid或者某个群组发送数据时,直接调用GatewayClient的接口Gateway::sendToUid Gateway::sendToGroup 等发送即可
通过浏览器访问sendMessage操作,测试结果
PS:以上的消息是TP5.0 通过 GatewayClient\Gateway 发送写消息,和GatewayWorker服务没有直接关系
以上为 服务端主动推送消息到客户端
注意区分:
1、服务端主动推送消息到客户端
2、客户端推送消息到客户端
(二)客户端推送消息到客户端
修改客户端到客户端的消息发送和接受,下面修改 GatewayWorker 的 Events.php(开发者只需要关注这个文件)
public static function onConnect($client_id) { $resData = [ 'type' => 'init', 'client_id' => $client_id, 'msg' => 'connect is success' // 初始化房间信息 ]; Gateway::sendToClient($client_id, json_encode($resData)); } /** * 当客户端发来消息时触发 * @param int $client_id 连接id * @param mixed $message 具体消息 */ public static function onMessage($client_id, $message) { // 服务端console输出 //echo "msg : $message \r\n"; // 解析数据 $resData = json_decode($message, true); $type = $resData['type']; $roomId = $resData['roomId']; $userId = $resData['userId']; // 未登录,则传递一个随机 $userName = $resData['userName']; // 未登录,则传递一个随机 $content = isset($resData['content']) ? $resData['content'] : 'default content'; //将时间全部置为服务器时间 $serverTime = date('Y-m-d H:i:s', time()); switch ($type) { case 'join': // 用户进入直播间 //将客户端加入到某一直播间 Gateway::joinGroup($client_id, $roomId); $resData = [ 'type' => 'join', 'roomId' => $roomId, 'userName' => $userName, 'msg' => "enters the Room", // 发送给客户端的消息,而不是聊天发送的内容 'joinTime' => $serverTime // 加入时间 ]; // 广播给直播间内所有人,谁?什么时候?加入了那个房间? Gateway::sendToGroup($roomId, json_encode($resData)); break; case 'say': // 用户发表评论 $resData = [ 'type' => 'say', 'roomId' => $roomId, 'userName' => $userName, 'content' => $content, 'commentTime' => $serverTime // 发表评论时间 ]; // 广播给直播间内所有人 Gateway::sendToGroup($roomId, json_encode($resData)); break; case 'pong': break; // 接收心跳 default: //Gateway::sendToAll($client_id,$json_encode($resData)); break; } }
index.html 聊天室页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>GatewayWorker的websocket连接</title> </head> <body> <h1>GatewayWorker的websocket连接</h1> <div> websocket send content:<input type="text" style="height: 50px; width: 100%;" name="data" id="data"> <p></p> <button id="submit" onclick="sub()">send info</button> <p></p> <div id="output"></div> </div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js"></script> <script language="javascript" type="text/javascript"> var wsUri = "ws://notes.env:7272/"; var outputContent; var roomId = 'L06777'; var userId = 4840043; var userName = 'Tinywan' + Math.random(); // 把当新链接的客户端加入到当前直播间,消息类型:{"type":"join","roomId":"1002","userId":"88","userName":"userName"} var joinContent = { "type": "join", "roomId": roomId, "userId": userId, "userName": userName }; // 初始化页面操作 function init() { outputContent = document.getElementById("output"); initWebSocket(); } function initWebSocket() { websocket = new ReconnectingWebSocket(wsUri); websocket.onopen = function (evt) { onOpen(evt) }; websocket.onclose = function (evt) { onClose(evt) }; websocket.onmessage = function (evt) { onMessage(evt) }; websocket.onerror = function (evt) { onError(evt) }; } function onOpen(evt) { console.log("CONNECTED"); } // 接收数据 function onMessage(evt) { var data = eval("(" + evt.data + ")"); var type = data.type || ''; switch (type) { case 'init': // 把当新链接的客户端加入到当前直播间 console.log('-------init--------' + data); websocket.send(JSON.stringify(joinContent)); writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data + '</span>'); break; case 'join': console.log('-------join--------' + data); writeToScreen( '<span style="color: blue;"> ' + ' 新用户: ' + '</span>' + '<span style="color: red;"> ' + data.userName + '</span>' + '<span style="color: green;"> ' + data.joinTime + '</span>' + '<span style="color: black;"> ' + data.msg + '</span>' ); break; case 'say': console.log('say======' + data); writeToScreen( '<span style="color: blue;"> ' + ' Chat: ' + '</span>' + '<span style="color: red;"> ' + data.userName + '</span>' + '<span style="color: #D2691E;"> ' + data.commentTime + '</span>' + '<span style="color: black;"> ' + data.content + '</span>' ); break; default : console.log(data); break; } } function onError(evt) { console.log('<span style="color: red;">ERROR:</span> ' + evt.data); } function onClose(evt) { console.log("DISCONNECTED"); } function writeToScreen(message) { var pre = document.createElement("p"); pre.style.wordWrap = "break-word"; pre.innerHTML = message; outputContent.appendChild(pre); } function sub() { var text = document.getElementById('data').value; // {"type":"say",,"msg":"Welcome 111111111111Live Room"} var sayContent = { "type": "say", "roomId": roomId, "userId": userId, "userName": userName, "content": text }; websocket.send(JSON.stringify(sayContent)); } window.addEventListener("load", init, false); </script> </body> </html>
重启开启服务
测试结果
扩展:
可以把消息存储的Redis中,通过Redis统计直播间的PV
$redis = new \Redis; $redis->connect('127.0.0.1',6379); $key = "PV:ROOM:".$roomId; $field = "ROOM_TOTAL_PV"; // 进入房间的人数增长,自增 ,增加PV统计 $redis->hIncrBy($key,$field,1);
相关推荐:《PHP教程》
Atas ialah kandungan terperinci ThinkPHP5.1框架与Workerman之GatewayWorker框架结合案例. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Untuk melaksanakan muat naik dan muat turun fail dalam dokumen Workerman, contoh kod khusus diperlukan. Pengenalan: Workerman ialah rangka kerja komunikasi rangkaian tak segerak PHP berprestasi tinggi yang ringkas, cekap dan mudah digunakan. Dalam pembangunan sebenar, muat naik dan muat turun fail adalah keperluan fungsi biasa Artikel ini akan memperkenalkan cara menggunakan rangka kerja Workerman untuk melaksanakan muat naik dan muat turun fail, dan memberikan contoh kod khusus. 1. Muat naik fail: Muat naik fail merujuk kepada operasi memindahkan fail pada komputer tempatan ke pelayan. Yang berikut digunakan

Swoole dan Workerman kedua-duanya adalah rangka kerja pelayan PHP berprestasi tinggi. Terkenal dengan pemprosesan tak segerak, prestasi cemerlang dan kebolehskalaannya, Swoole sesuai untuk projek yang perlu mengendalikan sejumlah besar permintaan serentak dan daya pemprosesan yang tinggi. Workerman menawarkan fleksibiliti mod tak segerak dan segerak, dengan API intuitif yang lebih sesuai untuk kemudahan penggunaan dan projek yang mengendalikan volum serentak yang lebih rendah.

Pengenalan kepada cara melaksanakan penggunaan asas dokumen Workerman: Workerman ialah rangka kerja pembangunan PHP berprestasi tinggi yang boleh membantu pembangun membina aplikasi rangkaian konkurensi tinggi dengan mudah. Artikel ini akan memperkenalkan penggunaan asas Workerman, termasuk pemasangan dan konfigurasi, mencipta perkhidmatan dan port mendengar, mengendalikan permintaan pelanggan, dsb. Dan berikan contoh kod yang sepadan. 1. Pasang dan konfigurasikan Workerman Masukkan arahan berikut pada baris arahan untuk memasang Workerman: c

Pembangunan pekerja: panggilan video masa nyata berdasarkan protokol UDP Ringkasan: Artikel ini akan memperkenalkan cara menggunakan rangka kerja Workerman untuk melaksanakan fungsi panggilan video masa nyata berdasarkan protokol UDP. Kami akan mempunyai pemahaman yang mendalam tentang ciri-ciri protokol UDP dan menunjukkan cara membina aplikasi panggilan video masa nyata yang ringkas tetapi lengkap melalui contoh kod. Pengenalan: Dalam komunikasi rangkaian, panggilan video masa nyata adalah fungsi yang sangat penting. Protokol TCP tradisional mungkin mempunyai masalah seperti kelewatan penghantaran apabila melaksanakan panggilan video masa nyata tinggi. Dan UDP

Cara melaksanakan fungsi proksi terbalik dalam dokumen Workerman memerlukan contoh kod khusus Pengenalan: Workerman ialah rangka kerja komunikasi rangkaian berbilang proses PHP berprestasi tinggi yang menyediakan fungsi yang kaya dan prestasi berkuasa dan digunakan secara meluas dalam komunikasi masa nyata Web dan panjang. sambungan. Antaranya, Workerman juga menyokong fungsi proksi terbalik, yang boleh merealisasikan pengimbangan beban dan caching sumber statik apabila pelayan menyediakan perkhidmatan luaran. Artikel ini akan memperkenalkan cara menggunakan Workerman untuk melaksanakan fungsi proksi terbalik.

Cara menggunakan Workerman untuk membina sistem pengimbangan beban dengan ketersediaan tinggi memerlukan contoh kod khusus Dalam bidang teknologi moden, dengan perkembangan pesat Internet, semakin banyak laman web dan aplikasi perlu mengendalikan sejumlah besar permintaan serentak. Untuk mencapai ketersediaan tinggi dan prestasi tinggi, sistem pengimbangan beban telah menjadi salah satu komponen penting. Artikel ini akan memperkenalkan cara menggunakan rangka kerja sumber terbuka PHP Workerman untuk membina sistem pengimbangan beban dengan ketersediaan tinggi dan menyediakan contoh kod khusus. 1. Pengenalan kepada Workerman Worke

Cara melaksanakan fungsi pemasa dalam dokumen Workerman Workerman ialah rangka kerja komunikasi rangkaian tak segerak PHP yang berkuasa yang menyediakan pelbagai fungsi, termasuk fungsi pemasa. Gunakan pemasa untuk melaksanakan kod dalam selang masa yang ditentukan, yang sangat sesuai untuk senario aplikasi seperti tugas yang dijadualkan dan tinjauan pendapat. Seterusnya, saya akan memperkenalkan secara terperinci cara melaksanakan fungsi pemasa dalam Workerman dan memberikan contoh kod khusus. Langkah 1: Pasang Workerman Mula-mula, kita perlu memasang Worker

Cara melaksanakan komunikasi TCP/UDP dalam dokumen Workerman memerlukan contoh kod khusus ialah rangka kerja tak segerak PHP berprestasi tinggi yang digunakan secara meluas untuk melaksanakan komunikasi TCP dan UDP. Artikel ini akan memperkenalkan cara menggunakan Workerman untuk melaksanakan komunikasi berasaskan TCP dan UDP serta memberikan contoh kod yang sepadan. 1. Komunikasi TCP Mencipta Pelayan TCP Menggunakan Workerman untuk mencipta pelayan TCP adalah sangat mudah Anda hanya perlu menulis kod berikut: <?ph
