| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 | <?phpuse Workerman\Worker;use Workerman\Timer;use PHPSocketIO\SocketIO;use Workerman\Protocols\Http\Request;use Workerman\Connection\TcpConnection;include __DIR__ . '/vendor/autoload.php';// 全局数组保存uid在线数据$uidConnectionMap = array();// 记录最后一次广播的在线用户数$last_online_count = 0;// 记录最后一次广播的在线页面数$last_online_page_count = 0;$context = array(    'ssl' => array(        'local_cert'  => '/www/wwwroot/1.wepolicy.cn/msg/erp.crt',        'local_pk'    => '/www/wwwroot/1.wepolicy.cn/msg/erp.key',        'verify_peer' => false,    ));// PHPSocketIO服务$sender_io = new SocketIO(2120,$context);// 客户端发起连接事件时,设置连接socket的各种事件回调$sender_io->on('connection', function($socket){    // 当客户端发来登录事件时触发    $socket->on('login', function ($uid)use($socket){        global $uidConnectionMap, $last_online_count, $last_online_page_count;        // 已经登录过了        if(isset($socket->uid)){            return;        }        // 更新对应uid的在线数据        $uid = (string)$uid;        if(!isset($uidConnectionMap[$uid]))        {            $uidConnectionMap[$uid] = 0;        }        // 这个uid有++$uidConnectionMap[$uid]个socket连接        ++$uidConnectionMap[$uid];        // 将这个连接加入到uid分组,方便针对uid推送数据        $socket->join($uid);        $socket->uid = $uid;        // 更新这个socket对应页面的在线数据        $username = '';            foreach ($uidConnectionMap as $k=>$v) 		    {				$username .= $k.'、';			}        $socket->emit('update_online_count', json_encode(array('num'=>$last_online_count,'username'=>trim($username,'、'))));//{$last_online_page_count}页面    });        // 当客户端断开连接是触发(一般是关闭网页或者跳转刷新导致)    $socket->on('disconnect', function () use($socket) {        if(!isset($socket->uid))        {             return;        }        global $uidConnectionMap, $sender_io;        // 将uid的在线socket数减一        if(--$uidConnectionMap[$socket->uid] <= 0)        {            unset($uidConnectionMap[$socket->uid]);        }    });});// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据$sender_io->on('workerStart', function(){    // 监听一个http端口    $inner_http_worker = new Worker('http://0.0.0.0:2121');    // 当http客户端发来数据时触发    $inner_http_worker->onMessage = function(TcpConnection $http_connection, Request $request){        global $uidConnectionMap;        $post = $request->post();        $post = $post ? $post : $request->get();        // 推送数据的url格式 type=publish&to=uid&content=xxxx        switch(@$post['type']){            case 'publish':                global $sender_io;                $to = @$post['to'];                $post['content'] = htmlspecialchars(@$post['content']);                // 有指定uid则向uid所在socket组发送数据                if($to){                  if($post['content'] == $to)					{						 $sender_io->to($to)->emit($to, $post['content']);					}					else					{                        $sender_io->to($to)->emit('new_msg', $post['content']);					}                // 否则向所有uid推送数据                }else{                    $sender_io->emit('new_msg', @$post['content']);                }                // http接口返回,如果用户离线socket返回fail                if($to && !isset($uidConnectionMap[$to])){                    return $http_connection->send('offline');                }else{                    return $http_connection->send('ok');                }        }        return $http_connection->send('fail');    };    // 执行监听    $inner_http_worker->listen();    // 一个定时器,定时向所有uid推送当前uid在线数及在线页面数    Timer::add(1, function(){        global $uidConnectionMap, $sender_io, $last_online_count, $last_online_page_count;        $online_count_now = count($uidConnectionMap);        $online_page_count_now = array_sum($uidConnectionMap);        // 只有在客户端在线数变化了才广播,减少不必要的客户端通讯        if($last_online_count != $online_count_now || $last_online_page_count != $online_page_count_now)        {            $username = '';            foreach ($uidConnectionMap as $k=>$v) 		    {				$username .= $k.'、';			}            $sender_io->emit('update_online_count', json_encode(array('num'=>$online_count_now,'username'=>trim($username,'、'))));//{$online_page_count_now} 页面            $last_online_count = $online_count_now;            $last_online_page_count = $online_page_count_now;        }    });});if(!defined('GLOBAL_START')){    Worker::runAll();}
 |