环境:
Workerman version: 3.5.1
PHP version: 5.6.30
Centos version: 6.8
workerman目录结构:
workerman
---App app开发目录
---ServerPush 服务器推模块
index.php
push_tcp.php
-+-Workerman wm核心目录(不修改)
_home_workerman_App_ServerPush_index_php.pid 守护进程号id
workerman.log 日志文件
index.php文件:
<?php use Workerman\Worker; require_once __DIR__ . '/../../Workerman/Autoloader.php'; $worker = new Worker('websocket://0.0.0.0:8888'); $worker->count = 1;//进程数 $worker->onWorkerStart = function() { //建立text协议进程,方便服务器内部调用推送 $inner_text_worker = new Worker('text://0.0.0.0:9988'); $inner_text_worker->onMessage = function($connection, $buffer) { $data = json_decode($buffer, true); if ($data['type'] === 'broadcast') { //广播 $result = broadcast($data['data']); } elseif ($data['type'] === 'byUid') { //独播 $result = sendMessageByUid($data['uid'], $data['data']); } $connection->send($result); }; $inner_text_worker->listen(); }; $worker->uidConnections = []; $worker->onMessage = function($connection, $data) { global $worker; //注册用户uid if(!isset($connection->uid)) { //以用户第一次发过来的uid为编号,正常流程是用户发账号密码,通过验证后存用户id $connection->uid = $data; $worker->uidConnections[$connection->uid] = $connection; return; } }; $worker->onClose = function($connection) { global $worker; //用户退出时告诉服务端,并清除uid if(isset($connection->uid)) { echo $connection->uid."已退出\n"; unset($worker->uidConnections[$connection->uid]); } }; //广播函数 function broadcast($message) { global $worker; $sum = 0; foreach($worker->uidConnections as $connection) { if($connection->send($message)) $sum++; } return "['all'=>".count($worker->uidConnections).",'success'=>$sum]"; } //独播函数 function sendMessageByUid($uid, $message) { global $worker; if(isset($worker->uidConnections[$uid])) { $connection = $worker->uidConnections[$uid]; $connection->send($message); return 'ok'; } return 'fail'; } Worker::runAll();
push_tcp.php文件:
<?php /** * Created by PhpStorm. * Date: 2017/10/28 * Time: 22:29 */ //建立tcp连接到text连接 $client = stream_socket_client('tcp://127.0.0.1:9988', $errno, $errmsg, 1); $data = ['type'=>'broadcast', 'data'=>'公告:近期收到站内有恶意诈骗事件,请各位不要相信站内非官方账号的信息']; //$data = ['type'=>'byUid', 'uid'=>'uid1', 'data'=>'uid1会员您好:近期收到站内有恶意诈骗事件,请不要相信站内非官方账号的信息']; //写入数据到tcp连接 fwrite($client, json_encode($data)."\n"); //读取连接返回信息 echo fread($client, 6666);
测试流程:
1)广播测试、发送给所有客户端
①守护进程方式启动index.php
②打开两个谷歌浏览器的控制台,分别建立 uid1 和 uid2 的websocket连接
var ws = new WebSocket('ws://xx:8888'); ws.onopen = function(){ var uid = 'uid1'; ws.send(uid); }; ws.onmessage = function(e){ document.body.innerText(e.data); };
回车之后可以点击Network看到已经建立了websocket连接了:
③执行push_tcp.php推送数据
④客户端收到数据
2)独播测试,发送消息给指定的uid
需要注释tcp_push.php的广播数据,启用独播,单独发送给uid1
//$data = ['type'=>'broadcast', 'data'=>'公告:近期收到站内有恶意诈骗事件,请各位不要相信站内非官方账号的信息']; $data = ['type'=>'byUid', 'uid'=>'uid1', 'data'=>'uid1会员您好:近期收到站内有恶意诈骗事件,请不要相信站内非官方账号的信息'];
①、②、③流程同上
④只有uid1的客户端收到消息
3)END
代码出自官方手册,本人略作修改
来自ansion博客
2017-10-29 11:32:43