好久之前写的功能 发现都忘了 记录一下
<?php
use Workerman\Worker;
use think\worker\Server;
use Workerman\Lib\Timer;
define('HEARTBEAT_TIME', 30); //心跳30秒
global $worker;
$worker = new Worker('websocket://0.0.0.0:1234');
// 这里进程数必须设置为1
$worker->count = 1;
// worker进程启动后建立一个内部通讯端口
$worker->onWorkerStart = function($worker)
{
// 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
$inner_text_worker = new Worker('Text://0.0.0.0:5678');
$inner_text_worker->onMessage = function($connection, $buffer)
{
global $worker;
// $data数组格式,里面有uid,表示向那个uid的页面推送数据
$data = json_decode($buffer, true);
$uid = $data['uid'];
$url=$data['url'];
// 通过workerman,向uid的页面推送数据
$ret = sendMessageByUid($uid, $url);
// 返回推送结果
$connection->send($ret ? 'ok' : 'fail');
};
$inner_text_worker->listen();
};
// 新增加一个属性,用来保存uid到connection的映射
$worker->uidConnections = array();
// 当有客户端发来消息时执行的回调函数
$worker->onMessage = function($connection, $data)use($worker)
{ $connection->lastMessageTime = time();
$wsData = json_decode($data,true);
// 判断当前客户端是否已经验证,既是否设置了uid
if(!isset($connection->uid))
{
// 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证)
$connection->uid=$wsData['uid'];
echo $wsData['uid']."shangxianle";
// $connection->uid = $data;
/* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
* 实现针对特定uid推送数据
*/
$worker->uidConnections[$connection->uid] = $connection;
return;
}
};
// 当有客户端连接断开时
$worker->onClose = function($connection)use($worker)
{
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)
{
echo $uid."----".$message;
global $worker;
if(isset($worker->uidConnections[$uid]))
{
$connection = $worker->uidConnections[$uid];
$connection->send($message);
return true;
}
return false;
}
// 运行所有的worker(其实当前只定义了一个)
Worker::runAll();
发送消息时
model
<?php
namespace app\index\model;
use think\Model;
use think\Session;
/**
*发送推送消息模型
*/
class Message extends Model {
/**
* [SendMessage 发送推送消息]
* @param [string] $url [需要推送的语音文件路径]
* @param [string] $uid [需要推送给的用户id]
* @return [status] [<成功:ok,失败:fail>]
*/
public function SendMessage($url,$uid){
// 建立socket连接到内部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
$data = array('uid'=>$uid,'url'=>$url);
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
$info=fwrite($client, json_encode($data)."\n");
// 读取推送结果
return fread($client, 8192);
}
}
前台连接时
<script type="text/javascript">
ws = new WebSocket("ws://pay.1d16.com:1234");
ws.onopen = function() {
var authid="{$authid}";
var data1={
"option":'login',
"uid":authid
};
ws.send(JSON.stringify(data1));
window.setInterval(function(){
ws.send('heart');
},5000);
};
ws.onmessage = function(e) {
var data=JSON.parse(e.data);
$("#audio").attr("src",data.voice);
var html='<a href="/index/user/receivedetail/id/'+data.id+'.html"><li class=" col-md-12">';
if(data.paymethod=="微信"){
html+='<img src="/pay/img/wx.png" >';
}else if(data.paymethod=="支付宝"){
html+='<img src="/pay/img/zfb.png" >';
}
html+='<div class="paylist-txt"><p>'+data.ordernum+'</p><p>'+data.addtime+'<span>支付成功</span></p></div><p class="paylist-price">'+data.money+'元</p></li></a>';
$(".paylist-title").after(html);
};
</script>
给前台发送消息
$voice= new Voice();
$v=$voice->getVoice("支付宝到账".$result['total_amount']."元",$out_trade_no);
$message= new Message();
$ord['voice']=$v;
$m=$message->SendMessage(json_encode($ord),$ord['receiveid']);
网友评论