user->identity->username,Yii::$app->user->identity->id 当前用户账号及id *domain 域名匹配 *expiretime 有效期判断 *$_FM['apiCert'] 服务器证书 */ $connection = yii::$app->db; $sql = "SELECT `username` FROM c_access WHERE accesstoken = :accesstoken AND domain = :domain AND expiretime > :expiretime ORDER BY id ASC"; $params = array(); $params[':accesstoken'] = $accessToken; $params[':domain'] = $viaDomain; $params[':expiretime'] = $timestamp; $result = fmFunc_pdo_yii_fetch($connection, $sql, $params); if ($result) { $username = $result['username']; //加载证书文件,但无用户登陆状态 $cert = $username . '.php'; if (file_exists($_HI['apiCertPath'] . $cert)) { $_FM['apiCert'] = array_merge(include($_HI['apiCertPath'] . $cert)); } } $_FM['apiCert']['token'] = $accessToken; //处理POST数据 $client_type = isset($dataPost['client_type']) ? $dataPost['client_type'] : 'undefined'; $isWeb = ($client_type == 'web') ? TRUE : FALSE; $isApp = ($client_type == 'app') ? TRUE : FALSE; $isAppWeb = ($client_type == 'appweb') ? TRUE : FALSE; $group_ids = array(); //根据当前用户身份生成可准确识别的用户ID $uid = isset($dataPost['uid']) ? $dataPost['uid'] : 'undefined'; $uid = fmFunc_server_hash_id($uid); $group_id = isset($dataPost['groupid']) ? $dataPost['groupid'] : 0; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; // client_id与uid绑定 Gateway::bindUid($client_id, $uid); // 加入某个群组(可调用多次加入多个群组) Gateway::joinGroup($client_id, $group_id); //当前用户所在的会员组 //继续根据创建更多分组 $do = isset($dataPost['do']) ? $dataPost['do'] : 'undefined'; $ac = isset($dataPost['ac']) ? $dataPost['ac'] : 'undefined'; $op = isset($dataPost['op']) ? $dataPost['op'] : 'undefined'; if ($isWeb) { $type = 'web'; $group_id = $type . '_' . $do . '_' . $ac . '_' . $op; $group_id = $group_pre . $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); $group_id = $type . '_' . $do . '_' . $ac; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); $group_id = $type . '_' . $do; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); } else { $type = 'app'; $group_id = $type . '_' . $do . '_' . $ac . '_' . $op; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); $group_id = $type . '_' . $do . '_' . $ac; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); $group_id = $type . '_' . $do; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); $group_id = $type; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); //当前用户并入前台用户组 if ($isAppWeb) { $type = 'appweb'; $group_id = $type; $group_id = $group_pre . fmFunc_server_hash_id($group_id); $group_ids[$group_id] = $group_id; Gateway::joinGroup($client_id, $group_id); //当前用户并入前台核销用户组 } } //发送反馈消息 $message = array(); $message = '棒,客户端绑定成功!'; $data = array(); $data['type'] = 'tips'; $data['msg'] = $message; $data['groupids'] = $group_ids; $data = json_encode($data); Gateway::sendToClient($client_id, $data); return; } /** * 接收客户端数据 */ public function actionIn() { $group_pre = 'VCMS-IMMS'; header('Access-Control-Allow-Origin:*'); //允许任何网站通过ajax发送请求 // 建立socket连接到内部推送端口 $client = stream_socket_client('tcp://127.0.0.1:4530'); //如果用户已经登陆,uid和群组id存在 //TBD 构建uid、group_id的生成方式 $uid = isset($dataPost['uid']) ? $dataPost['uid'] : 0; $group_id = isset($dataPost['group']) ? $dataPost['group'] : 0; //$client_id 通过前端传入 $client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : 0; // 推送的数据,包含uid字段,表示是给这个uid推送 $uid = isset(Yii::$app->user->identity->username) ? Yii::$app->user->identity->username : '0'; $data = array('uid' => $uid, 'msg' => urlencode('嗯,这个是测试用的')); // 发送数据,注意该端口是Text协议的端口,Text协议需要在数据末尾加上换行符 fwrite($client, json_encode($data) . "\n"); // 读取推送结果 // echo '$client=='.$client; //echo fread($client, 8192); } /** * 向客户端推送消息 */ public function actionOut() { global $_FM; //数据取出方法 $dataGet = $_FM['get']; //GET进来的参数 $dataPost = $_FM['post']; //POST进来的参数 $params = Yii::$app->params; header('Access-Control-Allow-Origin:*'); //允许任何网站通过ajax发送请求 require dirname(__FILE__) . '/_public/plat.php'; $group_pre = 'VCMS-IMMS'; /*设置REDIS缓存*/ //初始化$cache = new \Redis(); $cache = new \Redis(); $cache->connect($params['redis']['IP'], $params['redis']['PORT']); // 先检查是否存在,然后写入并设置有效时间 $key = 'FmWebSorcketCount'; $CACHE_PREFIX = 'DACMS'; $count = 0; if ($cache->exists($CACHE_PREFIX . $key)) { // 读取 $count = $cache->get($CACHE_PREFIX . $key); //清除 $cache->delete($CACHE_PREFIX . $key); } $cache->set($CACHE_PREFIX . $key, $count + 1); $expire = time() + 604800; //一周时间再过期 $cache->expire($CACHE_PREFIX . $key, $expire); //前台已经建立起长链接,取得了客户端ID号;需要绑定到当前用户,并返回用户uid,供服务侧同步绑定校验 $viaDomain = fmFunc_server_via_domain(); //来路域名 $viaIP = fmFunc_server_via_ip(); //来路IP $timestamp = isset($_FM['timestamp']) ? $_FM['timestamp'] : time(); //通过前端GET传入的 $client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : '7f000001b0f400000010'; $accessToken = isset($dataGet['accesstoken']) ? $dataGet['accesstoken'] : 0; //判断accesstoken有效性 /* @有效性规则判断 *Yii::$app->user->identity->username,Yii::$app->user->identity->id 当前用户账号及id *domain 域名匹配 *expiretime 有效期判断 *$_FM['apiCert'] 服务器证书 */ $connection = yii::$app->db; $sql = "SELECT `username` FROM c_access WHERE accesstoken = :accesstoken AND domain = :domain AND expiretime > :expiretime ORDER BY id ASC"; $params = array(); $params[':accesstoken'] = $accessToken; $params[':domain'] = $viaDomain; $params[':expiretime'] = $timestamp; $result = fmFunc_pdo_yii_fetch($connection, $sql, $params); $hasToken = FALSE; $hasCert = FALSE; if ($result) { $username = $result['username']; $hasToken = TRUE; //加载证书文件,但无用户登陆状态 $cert = $username . '.php'; if (file_exists($_HI['apiCertPath'] . $cert)) { $_FM['apiCert'] = array_merge(include($_HI['apiCertPath'] . $cert)); $hasCert = TRUE; } } $_FM['apiCert']['token'] = $accessToken; //处理POST数据 $client_type = isset($dataPost['client_type']) ? $dataPost['client_type'] : ''; $msg_type = isset($dataPost['msg_type']) ? $dataPost['msg_type'] : ''; if (!$msg_type) { $msg_type = isset($dataGet['msg_type']) ? $dataGet['msg_type'] : ''; } $isWeb = ($client_type == 'web') ? TRUE : FALSE; $isApp = ($client_type == 'app') ? TRUE : FALSE; $isAppWeb = ($client_type == 'appweb') ? TRUE : FALSE; $msg = isset($dataPost['msg']) ? $dataPost['msg'] : ''; if (!$msg) { $msg = isset($dataGet['msg']) ? $dataGet['msg'] : ''; } //构造反馈消息 $data = array(); $data['type'] = $msg_type; $data['msg'] = $msg; if (isset($dataGet['debug'])) { //向全体推送数据 $data['msg'] = empty($data['msg']) ? '第' . $count . '次测试群发' : $data['msg']; $count++; $data = json_encode($data); Gateway::sendToAll($data); return; } $data = json_encode($data); //根据情况发送消息 switch ($hasToken) { case TRUE: //根据当前用户身份生成可准确识别的用户ID $uid = isset($dataPost['uid']) ? $dataPost['uid'] : ''; if ($uid) { $uid = fmFunc_server_hash_id($uid); Gateway::sendToUid($uid, $data); } //有证书时,可继续下一步的推送 if (!$hasCert) { break; //无证书,不再继续 } //已指派分组时 $group_id = isset($dataPost['group']) ? $dataPost['group'] : 0; if ($groud_id) { $group_id = $group_pre . fmFunc_server_hash_id($group_id); Gateway::sendToGroup($group_id, $data); break; //执行后结束此次推送 } //根据创建更多分组 $do = isset($dataPost['do']) ? $dataPost['do'] : ''; $ac = isset($dataPost['ac']) ? $dataPost['ac'] : ''; $op = isset($dataPost['op']) ? $dataPost['op'] : ''; if ($client_type) { if ($isWeb) { $type = 'web'; } else if ($isAppWeb) { $type = 'appweb'; } else { $type = 'app'; } if ($do) { if ($ac) { if ($op) { $group_id = $type . '_' . $do . '_' . $ac . '_' . $op; $group_id = $group_pre . fmFunc_server_hash_id($group_id); Gateway::sendToGroup($group_id, $data); } else { $group_id = $type . '_' . $do . '_' . $ac; $group_id = $group_pre . fmFunc_server_hash_id($group_id); Gateway::sendToGroup($group_id, $data); } } else { $group_id = $type . '_' . $do; $group_id = $group_pre . fmFunc_server_hash_id($group_id); Gateway::sendToGroup($group_id, $data); } } else { $group_id = $type; $group_id = $group_pre . fmFunc_server_hash_id($group_id); Gateway::sendToGroup($group_id, $data); } } break; case FALSE; //只发送给指定客户端 Gateway::sendToClient($client_id, $data); break; } // 以下是调用示例,接口与GatewayWorker环境的接口一致 // 接口具体使用方法见《Lib\Gateway类提供的接口》一章 // 注意除了不支持sendToCurrentClient和closeCurrentClient方法 // 其它方法都支持 //Gateway::sendToAll($data); //Gateway::sendToClient($client_id, $data); //Gateway::closeClient($client_id); //Gateway::isOnline($client_id); //Gateway::bindUid($client_id, $uid); //Gateway::isUidOnline($uid); //Gateway::getClientIdByUid($uid); //Gateway::unbindUid($client_id, $uid); //Gateway::sendToUid($uid, $data); //Gateway::joinGroup($client_id, $group); //Gateway::sendToGroup($group, $data); //Gateway::leaveGroup($client_id, $group); //Gateway::getClientCountByGroup($group); //Gateway::getClientSessionsByGroup($group); //Gateway::getAllClientCount(); //Gateway::getAllClientSessions(); //Gateway::setSession($client_id, $session); //Gateway::updateSession($client_id, $session); //Gateway::getSession($client_id); } }