📖 File Reader
<?php
namespace app\api\controller;
use think\facade\Db;
use think\facade\View;
use think\worker\Server;
use Workerman\Lib\Timer;
//define('HEARTBEAT_TIME', 1);// 心跳间隔55秒
class Websocket extends Server
{
protected $socket = 'websocket://0.0.0.0:2346';
protected $userlist = [];//在线会员
protected $is_chufa = false;//触发状态
protected $app_key = '35a5c75b78b6f38824586257';//极光AppKey
protected $master_secret = '2048c8de00db915774f7d652';//极光Master Secret
protected $url = "https://api.jpush.cn/v3/push";//极光推送的地址
public function index()
{
return View::fetch();
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
//$connection->send('连接成功');
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
$connection->send('断开');
}
/**
* 收到信息
* @param $connection 会员信息
* @param $data 前台传的参数
*/
public function onMessage($connection, $data)
{
$data_arr = json_decode($data,true);
//存储会员
global $user_list;
if (!empty($data_arr['uid'])) {
$uid = $data_arr['uid'];
$user_list["uidConnections"][$uid] = $connection;
session("user_list", $user_list);
$connection->uid = $uid;
}
$data = [
'request_data'=>$data_arr,
'time_tuisong'=>date("Y-m-d H:i:s",time()),
];
$connection->send(json_encode($data));//发送请求参数
if ($data_arr["type"] == 1){ //聊天触发通知
$this->chat_personnel_inform($data_arr["cart_id"]);
}
if ($this->is_chufa == false){ //只触发一次(不会因为其他会员导致重复执行)
//$this->article_inform();
/*创建记录并更改状态*/
$time = time();
$info = [
'time_add'=>$time,
'time_tuisong'=> date("Y-m-d H:i:s",$time),
];
db::name("websocket")->insertGetId($info);
$this->is_chufa = true;
}
}
/*通知公告*/
public function article_inform()
{
Timer::add(5, function () {
global $user_list;//全部会员信息
$userlist = $this->userlist;
$user_id = '';//全部在线会员id
foreach ($userlist as $v) {
$user_id .= $v.',';
}
$user_id = substr($user_id,0,strlen($user_id)-1);
$user_id_arr = [];
if (!empty($user_id)){ //去重复
$user_id_arr = array_unique(explode(',',$user_id));
$user_id = implode(",", $user_id_arr);
}
/*逻辑编写*/
//测试推送
$data = [
'userlist'=>$userlist,
'time'=>date("Y-m-d H:i:s",time()),
];
$connection = $user_list['uidConnections']["1"];
$connection->send(json_encode($data));
});
}
/**
* 聊天同窗口推送
* @param int $cart_id 聊天窗口id
* @return void
*/
public function chat_personnel_inform($cart_id=0)
{
global $user_list;//全部会员信息
$chat_personnel = db::name("chat_personnel")->where("id = $cart_id")->find();
$user_id_arr = explode(',',$chat_personnel['user_id_str']);
$data = [
'chat_personnel'=>$chat_personnel,
'type'=>1,
'time'=>date("Y-m-d H:i:s",time()),
];
foreach ($user_id_arr as $v){
$connection = $user_list['uidConnections'][$v];
$connection->send(json_encode($data));
}
}
/**
* 单独一个人推送
* @param $uid 会员id
* @param $Message 推送内容
*/
public function sendMessageByUid($uid,$Message)
{
global $user_list;
$connection = $user_list["uidConnections"][$uid];
$connection->send($Message);
}
/**
* 向所有验证的用户推送数据
* @param $message 推送内容
*/
function broadcast($message)
{
global $user_list;
//遍历全局数组,然后发送数据
foreach ($user_list["uidConnections"]as $connection) {
$connection->send($message);
}
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
//查看是否有新的下面的3是几秒推送一次
Timer::add(5, function () use ($worker) {
$userlist = [];
foreach ($worker->connections as $connections) { //所有会员循环在线会员
if (!empty($connections->uid)){
$userlist[] = $connections->uid;
}
}
$this->userlist = $userlist;//存储在线会员
});
}
/*极光推送处理*/
public function test_push(){
//推送
$param = [
'receiver' => [
'alias' => [
'123456'
]
],
'title' => '993同城快车',
'content' => '保活测试',
'extras' => [
'code' => '1',
'url'=>'https://dache.gkktc.cn/public/image/uniapp/yuyin/tishiyin.mp3'
],
'm_time' => 60,
];
$base64 = base64_encode("$this->app_key:$this->master_secret");
$header = array("Authorization:Basic $base64", "Content-Type:application/json");
$data = array();
$data['platform'] = 'android'; //目标用户终端手机的平台类型android,ios,winphone
$data['audience'] = $param['receiver']; //目标用户
//发送通知
$data['notification'] = array(
//统一的模式--标准模式
//"alert"=>$content,
//安卓自定义
"android" => array(
"alert" => $param['content'],
"title" => $param['title'],
"builder_id" => 1,
"extras" => $param['extras'],
),
//ios的自定义
"ios" => array(
"alert" => $param['content'],
"badge" => "1",
"sound" => "default",
"extras" => $param['extras'],
),
);
//自定义信息
$data['message'] = array(
"msg_content" => $param['content'],
"extras" => $param['extras'],
);
//附加选项
$data['options'] = array(
"sendno" => time(),
//"time_to_live" => $param['m_time'], //保存离线时间的秒数默认为一天
"apns_production" => 0, //指定 APNS 通知发送环境:0开发环境,1生产环境。
);
$param = json_encode($data);
$res = json_decode($this->push_curl($param, $header));
if (!isset($res->error)){
return true;
}
return false;
}
//推送的Curl方法
public function push_curl($param = "", $header = "")
{
if (empty($param)) {
return false;
}
$postUrl = $this->url;
$curlPost = $param;
$ch = curl_init(); //初始化curl
curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); // 增加 HTTP Header(头)里的字段
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 终止从服务端进行验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$data = curl_exec($ch); //运行curl
curl_close($ch);
return $data;
}
}