一个简单的使用Workerman实现WEB端消息推送示例
服务端server.php代码
<?php
use Workerman\Lib\Timer; use Workerman\Worker; require_once './Workerman/Autoloader.php'; // 心跳间隔55秒 define('HEARTBEAT_TIME', 55); // 初始化一个worker容器,监听1234端口 $worker = new Worker('websocket://0.0.0.0:1234'); /* * 注意这里进程数必须设置为1,否则会报端口占用错误 * (php 7可以设置进程数大于1,前提是$inner_text_worker->reusePort=true) */ $worker->count = 1; // worker进程启动后创建一个text Worker以便打开一个内部通讯端口 $worker->onWorkerStart = function($worker) { Timer::add(1, function()use($worker){ $time_now = time(); foreach($worker->connections as $connection) { // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间 if (empty($connection->lastMessageTime)) { $connection->lastMessageTime = $time_now; continue; } // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接 if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) { $connection->close(); } } }); // 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符 $inner_text_worker = new Worker('text://0.0.0.0:5678'); $inner_text_worker->onMessage = function($connection, $buffer) { // $data数组格式,里面有uid,表示向那个uid的页面推送数据 $data = json_decode($buffer, true); $uid = $data['uid']; // 通过workerman,向uid的页面推送数据 $ret = sendMessageByUid($uid, $buffer); // 返回推送结果 $connection->send($ret ? 'ok' : 'fail'); }; // ## 执行监听 ## $inner_text_worker->listen(); }; // 新增加一个属性,用来保存uid到connection的映射 $worker->uidConnections = array(); // 当有客户端发来消息时执行的回调函数 $worker->onMessage = function($connection, $data) { global $worker; // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间 $connection->lastMessageTime = time(); // 判断当前客户端是否已经验证,既是否设置了uid if(!isset($connection->uid)) { // 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证) $connection->uid = $data; /* 保存uid到connection的映射,这样可以方便的通过uid查找connection, * 实现针对特定uid推送数据 */ $worker->uidConnections[$connection->uid] = $connection; return; } }; // 当有客户端连接断开时 $worker->onClose = function($connection) { global $worker; if(isset($connection->uid)) { // 连接断开时删除映射 unset($worker->uidConnections[$connection->uid]); } }; // 向所有验证的用户推送数据 function broadcast($message) { global $worker; foreach($worker->uidConnections as $connection) { $connection->send($message); } } // 针对uid推送数据 function sendMessageByUid($uid, $message) { global $worker; if(isset($worker->uidConnections[$uid])) { $connection = $worker->uidConnections[$uid]; $connection->send($message); return true; } return false; } // 运行所有的worker Worker::runAll();
客户端client.html代码
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>DEMO</title>
<script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased
}
#messages {
list-style-type: none;
margin: 0;
overflow: auto;
overflow-x: hidden
}
#messages, li p {
word-wrap: break-word
}
li p {
margin-left: 56px
}
.header {
text-align: center;
color: #eee;
font-weight: 200;
font-size: 24px;
margin: 60px
}
.test {
box-shadow: 0 2px 3px rgba(0, 0, 0, .1);
-webkit-box-shadow: 2px 2px 5px #333;
box-shadow: 2px 2px 5px #333
}
.main {
background-color: #fff
}
.main, .main_header {
border-radius: 4px 4px 0 0
}
.main_header {
background-color: #eee;
margin: 0;
color: #666;
padding: 2px 0;
font-size: 12px
}
.main_header, .qrcode {
text-align: center
}
.qrcode img {
width: 160px;
border-radius: 10px;
height: 160px
}
#messages {
padding: 8px;
background-color: #000;
color: #dc3545;
text-align: left;
font-size: 12px;
height: 100%
}
.gray {
color: #666
}
.green {
color: green
}
.blue {
color: #007bff
}
.yellow {
color: #ffc107
}
.center {
text-align: center
}
.gray a {
text-decoration: none
}
.test {
max-width: 800px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="main">
<div class="test">
<div class="main_header">websocket演示</div>
<ul id="messages" style="min-height: 380px; height: 380px;">
</ul>
</div>
</div>
</body>
<script>
//这里的ip地址改为自己服务器的ip地址
var ws = new WebSocket('ws://127.0.0.1:1234');
ws.onopen = function () {
var uid = 'uid1';
ws.send(uid);
var html = '<li><span class="yellow">已连接</span></li>';
$("#messages").append(html);
};
ws.onmessage = function (e) {
var message_info = JSON.parse(e.data)
var html = '<li><span class="blue">' + message_info.content + '</span></li>';
$("#messages").append(html);
};
</script>
</html>
推送接口push.php(调用该文件实现消息推送)
// 建立socket连接到内部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
$data = array('uid'=>'uid1', 'content'=>'啦啦啦 啦啦啦 我是卖报的小行家');
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($data)."\n");
// 读取推送结果
echo fread($client, 8192);
// 建立socket连接到内部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
$data = array('uid'=>'uid1', 'content'=>'啦啦啦 啦啦啦 我是卖报的小行家');
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($data)."\n");
// 读取推送结果
echo fread($client, 8192);
演示步骤
1、启动server.php服务端
php server.php start
2、浏览器中输入客户端网址,打开客户端网页
http://127.0.0.1/client.html
3、浏览器打开push.php或在命令行执行php push.php
http://127.0.0.1/push.php
4、观察客户端显示的效果
本站素材来自用户分享,仅限学习交流请勿用于商业用途。如损害你的权益请联系客服QQ:201240120 给予处理。
还没有评论哦!