| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <?php
- /**
- * This file is part of workerman.
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the MIT-LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @author walkor<walkor@workerman.net>
- * @copyright walkor<walkor@workerman.net>
- * @link http://www.workerman.net/
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
- /**
- * 用于检测业务代码死循环或者长时间阻塞等问题
- * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
- * 然后观察一段时间workerman.log看是否有process_timeout异常
- */
- //declare(ticks=1);
- namespace addons\fastchat\library\GatewayWorker\Applications\FastChat;
- use addons\fastchat\library\Common;
- use GatewayWorker\Lib\Gateway;
- use Workerman\Lib\Timer;
- use think\Db;
- /**
- * 主逻辑
- * 主要是处理 onConnect onMessage onClose 三个方法
- * onConnect 和 onClose 如果不需要可以不用实现并删除
- */
- class Events
- {
- /**
- * WebSocket 链接成功
- *
- * @param int $client_id data
- * @param $[data] [websocket握手时的http头数据,包含get、server等变量]
- */
- public static function onWebSocketConnect($client_id, $data)
- {
- // 安全检查
- array_walk_recursive($data, array('addons\fastchat\library\Common', 'check_variable'));
- $config_data = get_addon_config('fastchat');
- $_SESSION['origin'] = 'http://' . $data['server']['SERVER_NAME'];//设置服务器域名
- if (!$config_data['anonymous_to_admin'] && !$config_data['anonymous_to_user'] && !$data['get']['token']) {
- // 禁止匿名发起会话,确认用户收到登录提示后,直接关闭链接
- Gateway::sendToClient($client_id, json_encode(['msgtype' => 'clear', 'code' => 401]));
- return;
- }
- // 获取连接人信息
- $token_info = false;
- if ($data['get']['modulename'] == 'admin' && $data['get']['token']) {
- // 验证管理员身份
- $token_info = Common::check_admin($data['get']['token']);
- // 设置定时器,定时检测管理员身份是否过期
- // $_SESSION['auth_timer_id'] = Timer::add(30, function ($client_id, $token) {
- // $token_info = Common::check_admin($token);
- // if (!$token_info) {
- // Gateway::closeClient($client_id);
- // }
- // }, array($client_id, $data['get']['token']));
- } else if ($data['get']['modulename'] == 'user' && $data['get']['token']) {
- // 验证用户身份
- $token_info = Common::check_fa_user($data['get']['token'], 0);
- if ($token_info && $data['get']['fastchat_user']) {
- // 游客登录了
- Common::tourists_to_login($data['get']['fastchat_user'], $token_info['user_id']);
- }
- } else if ($data['get']['modulename'] == 'index' && $data['get']['fastchat_user']) {
- // 验证游客身份
- $token_info = Common::check_tourists($data['get']['fastchat_user']);
- if ($token_info && !$config_data['anonymous_to_admin'] && !$config_data['anonymous_to_user']) {
- // 禁止匿名发起会话,确认用户收到登录提示后,直接关闭链接
- Gateway::sendToClient($client_id, json_encode(['msgtype' => 'clear', 'code' => 401]));
- }
- } else if ($data['get']['modulename'] == 'massager' && $data['get']['token']) {
- // 验证助教登录
- $token_info = Common::check_massager($data['get']['token']);
- }
- if ($token_info) {
- Gateway::bindUid($client_id, $token_info['user_id']);
- $_SESSION['user_id'] = $token_info['user_id'];
- } else {
- Gateway::sendToClient($client_id, json_encode([
- 'msgtype' => 'welcome_tourists',
- 'code' => 0,
- 'msg' => '未找到token!'
- ]));
- Gateway::closeClient($client_id);
- }
- // else if ($data['get']['modulename'] != 'admin') {
- // // 建立游客身份,cookie值发送到前台保存->已废弃,转由http处理
- // $tourists_max_id = Db::name('fastchat_tourists')->max('id');
- //
- // $token = Random::uuid();
- // $tourists = [
- // 'avatar' => '',// 随机头像->算了算了
- // 'nickname' => '游客 ' . $tourists_max_id,
- // 'token' => $token,
- // 'createtime' => time()
- // ];
- //
- // if (Db::name('fastchat_tourists')->insert($tourists)) {
- //
- // $tourists_id = Db::name('fastchat_tourists')->getLastInsID();
- //
- // $_SESSION['user_id'] = $tourists_id . '||tourists';
- // Gateway::bindUid($client_id, $_SESSION['user_id']);
- //
- // $keeptime = 864000;
- // $expiretime = time() + $keeptime;
- // $key = md5(md5($tourists_id) . md5($keeptime) . md5($expiretime) . $token);
- // $data = [$tourists_id, $keeptime, $expiretime, $key];
- //
- // // 为游客登录
- // $fastchat_tourists = implode('|', $data);
- // $token_info = Common::check_tourists($fastchat_tourists);
- // $_SESSION['user_id'] = $token_info['user_id'];
- //
- // Gateway::sendToClient($client_id, json_encode([
- // 'msgtype' => 'welcome_tourists',
- // 'code' => 1,
- // 'data' => $fastchat_tourists
- // ]));
- // } else {
- // Gateway::sendToClient($client_id, json_encode([
- // 'msgtype' => 'welcome_tourists',
- // 'code' => 0,
- // 'msg' => '会话服务异常!'
- // ]));
- // }
- //
- // } else {
- // $_SESSION['user_id'] = $client_id;
- // }
- $config_data['new_msg'] = Common::get_unread_messages($_SESSION['user_id'], true);
- $config_data['user_info'] = $token_info;
- $config_data['service_user'] = Db::name("fastchat_service_user")->order("id", "ASC")->find();
- // 向当前client_id发送数据
- Gateway::sendToClient($client_id, json_encode(['msgtype' => 'config', 'data' => $config_data]));
- // 向所有人发送
- Gateway::sendToAll(json_encode([
- 'msgtype' => 'online',
- 'user_id' => $_SESSION['user_id']
- ]));
- }
- /**
- * 当客户端发来消息时触发
- * @param int $client_id 连接id
- * @param mixed $message 具体消息
- */
- public static function onMessage($client_id, $message)
- {
- // 分发到控制器
- $data = json_decode($message, true);
- // 安全检查
- array_walk_recursive($data, array('addons\fastchat\library\Common', 'check_variable'));
- if (!is_array($data) || !isset($data['c']) || !isset($data['a'])) {
- $res_data = array('msgtype' => 'notice', 'msg' => '错误的请求!');
- Gateway::sendToClient($client_id, json_encode($res_data));
- return;
- }
- if ($data['c'] == 'clear') {
- Gateway::closeClient($client_id);
- return '';
- }
- $filename = __DIR__ . '/controller/' . $data['c'] . '.php';//载入文件类似/controller/index.php
- if (file_exists($filename)) {
- require_once($filename);
- /*
- 检查要访问的类是否存在
- */
- if (!class_exists($data['c'], false)) {
- $res_data = array('msgtype' => 'notice', 'msg' => '您访问的控制器不存在!');
- Gateway::sendToClient($client_id, json_encode($res_data));
- return '';
- }
- } else {
- $res_data = array('msgtype' => 'notice', 'msg' => '您访问的页面并存在!');
- Gateway::sendToClient($client_id, json_encode($res_data));
- return '';
- }
- $o = new $data['c'](); // 新建对象
- if (!method_exists($o, $data['a'])) {
- $res_data = array('msgtype' => 'notice', 'msg' => '您访问的方法并存在!');
- Gateway::sendToClient($client_id, json_encode($res_data));
- return '';
- }
- $data['data'] = isset($data['data']) ? $data['data'] : '';
- call_user_func_array(array($o, $data['a']), array($client_id, $data['data']));//调用对象$o($c)里的方法$a
- }
- /**
- * 当用户断开连接时触发
- * @param int $client_id 连接id
- */
- public static function onClose($client_id)
- {
- if (isset($_SESSION['auth_timer_id'])) {
- Timer::del($_SESSION['auth_timer_id']);
- }
- // 向所有人发送
- if (isset($_SESSION['user_id'])) {
- $user_info = Common::user_info($_SESSION['user_id']);
- if (($user_info['session_type'] != 5) || ($user_info['session_type'] == 5 && $user_info['online_status'] == 1)) {
- Gateway::sendToAll(json_encode([
- 'msgtype' => 'offline',
- 'user_id' => $_SESSION['user_id']
- ]));
- }
- }
- }
- }
|