ctms/dacms-home/controllers/PushimmsController.php
fm453 314745edf8 优化ctms-api语法、修复已知BUG;
主要修复ctms-api、dacms对PHP新版本的支持问题
2025-04-10 23:19:15 +08:00

516 lines
17 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @Author: fm453
* @Date: 2019-04-27 22:19:28
* @Last Modified by: fm453
* @Last Modified time: 2019-04-29 17:08:02
*/
/**
* 利用workerman制作的推送接口控制器(针对vcms的fm453_*系列应用)
*/
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use dataModel;
//必须添加这一句以便引入dataModel外部类库
// 引用GateWay Client
require(__DIR__ . '/../../vendor/workerman/GatewayClient-3.0.0/Gateway.php');
// GatewayClient 3.0.0版本开始要使用命名空间
use GatewayClient\Gateway;
// 设置GatewayWorker服务的Register服务ip和端口
Gateway::$registerAddress = '127.0.0.1:4530';
class PushimmsController extends Controller
{
public $enableCsrfValidation = FALSE;//取消对POST数据的csrf令牌验证
/**
* 绑定客户端与指定客户id\分组id
*/
public function actionBind()
{
global $_FM;
//数据取出方法
$dataGet = $_FM['get']; //GET进来的参数
$dataPost = $_FM['post']; //POST进来的参数
$data = array();
header('Access-Control-Allow-Origin:*'); //允许任何网站通过ajax发送请求
require dirname(__FILE__) . '/_public/plat.php';
$group_pre = 'VCMS-IMMS';
//前台已经建立起长链接取得了客户端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'] : 0;
$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);
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);
// client_id与uid绑定
Gateway::bindUid($client_id, $uid);
$group_id = isset($dataPost['groupid']) ? $dataPost['groupid'] : 0;
if ($group_id) {
$group_ids[0] = $group_pre . fmFunc_server_hash_id(0);;
// 加入某个群组(可调用多次加入多个群组)
Gateway::joinGroup($client_id, $group_id); //当前用户所在的会员组
}
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
// 加入某个群组(可调用多次加入多个群组)
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:https://vcms.hiluker.com'); //允许指定网站通过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:https://vcms.hiluker.com'); //允许指定网站通过ajax发送请求
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;
}
}
/**
* 接收客户端数据并向全部客户端群发
*/
public function actionSend2all()
{
// header('Access-Control-Allow-Origin:https://vcms.hiluker.com'); //允许指定网站通过ajax发送请求
header('Access-Control-Allow-Origin:*'); //允许指定网站通过ajax发送请求
global $_FM;
global $_HI;
//数据取出方法
$dataGet = $_FM['get']; //GET进来的参数
$dataPost = $_FM['post']; //POST进来的参数
$params = Yii::$app->params;
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'] : ' ';
if (!$client_id) {
return;
}
$accessToken = isset($dataGet['accesstoken']) ? $dataGet['accesstoken'] : '';
if (!$accessToken) {
//构造反馈消息
$data = array();
$data['type'] = 'log';
$data['msg'] = '未指定accessToken';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
//判断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 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;
}
} else {
//构造反馈消息
$data = array();
$data['type'] = 'log';
$data['msg'] = '无效的accessToken';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
$_FM['apiCert']['token'] = $accessToken;
//处理POST数据
$msg_type = isset($dataPost['msg_type']) ? $dataPost['msg_type'] : '';
if (!$msg_type) {
$msg_type = isset($dataGet['msg_type']) ? $dataGet['msg_type'] : '';
}
$msg = isset($dataPost['msg']) ? $dataPost['msg'] : '';
if (!$msg) {
$msg = isset($dataGet['msg']) ? $dataGet['msg'] : '';
}
//设定群发群组
$group_id = $group_pre . fmFunc_server_hash_id(0);
//构造反馈消息
$data = array();
$data['type'] = $msg_type;
// $data['type'] = 'alert';
$data['msg'] = $msg;
if (isset($dataGet['debug'])) {
//向全体推送数据
$data['msg'] = empty($data['msg']) ? '第' . $count . '次测试群发' : $data['msg'];
$count++;
$data = json_encode($data);
Gateway::sendToGroup($group_id, $data);
return;
}
$data = json_encode($data);
//向全体推送数据
$count++;
Gateway::sendToGroup($group_id, $data);
//构造反馈消息
$data = array();
$data['type'] = 'toast';
$data['msg'] = '消息已发送';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
}