workerman

作者: define光年 | 来源:发表于2020-09-09 15:23 被阅读0次

    好久之前写的功能 发现都忘了 记录一下

    <?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']);

    相关文章

      网友评论

          本文标题:workerman

          本文链接:https://www.haomeiwen.com/subject/xzveektx.html