115 lines
4.9 KiB
PHP
115 lines
4.9 KiB
PHP
<?php
|
||
namespace app\http;
|
||
use app\facade\RedisCache;
|
||
use app\http\service\ChatCloseService;
|
||
use app\http\service\ChatMessageService;
|
||
use app\http\service\ChatService;
|
||
use app\http\service\MessageQueueService;
|
||
use think\facade\Log;
|
||
use think\swoole\Server;
|
||
class Swoole extends Server
|
||
{
|
||
protected $serverType = 'socket';
|
||
protected $port = 9502;
|
||
protected $sockType = SWOOLE_SOCK_TCP | SWOOLE_SSL;
|
||
protected $option = [
|
||
'worker_num'=> 4,
|
||
'task_worker_num' => 4,
|
||
'daemonize' => true,
|
||
'backlog' => 128,
|
||
'heartbeat_idle_time' => 600,
|
||
'heartbeat_check_interval' => 60,
|
||
'ssl_cert_file' => '/usr/local/nginx/conf/cert/jinhu11.pem',
|
||
'ssl_key_file' => '/usr/local/nginx/conf/cert/jinhu11.key',
|
||
];
|
||
|
||
public function onOpen($server, $request)
|
||
{
|
||
//建立连接时,应将用户信息入缓存,并将客服分配给该用户
|
||
//Cache::setCliUser($request->fd,['id'=>$request->fd, 'ip'=>$request->server['remote_addr']]);
|
||
//echo '连接建立';
|
||
//echo json_encode($request);
|
||
//Log::info(json_encode($request));
|
||
//Log::info('读$_COOKIE参数'.json_encode($_COOKIE));
|
||
//Log::info('读cookie参数'.$request->cookie['PHPSESSID']);
|
||
//取缓存
|
||
//Log::info('session原会话信息'.Cache::store('session_store')->get($request->cookie['PHPSESSID']));
|
||
//$session_data=$this->unserialize_php(Cache::store('session_store')->get($request->cookie['PHPSESSID']));
|
||
//读取user_id
|
||
//如果不存在user_id,则为游客,随机分配在线客服
|
||
//如果存在user_id,则查询专属客服,若专属客服不在线,则随机分配在线客服
|
||
//Log::info('session自解码会话信息'.json_encode();
|
||
$chat_deal=new ChatService($server,$request);
|
||
$chat_deal->onOpen();
|
||
}
|
||
|
||
public function onMessage($server, $frame) {
|
||
//收到消息,根据用户信息发给指定人
|
||
$chat_message_deal=new ChatMessageService($server,$frame);
|
||
$chat_message_deal->deal();
|
||
|
||
/*$data = json_decode($frame->data,true);
|
||
switch ($data['type']) {
|
||
case 'openService' :
|
||
$chat_deal=new ChatService($server,$frame->fd,$data);
|
||
$result=$chat_deal->openService();
|
||
break;
|
||
default:
|
||
$result['message_type']='error';
|
||
$result['data']=['错误消息类型'];
|
||
}
|
||
$server->push($frame->fd,myResult($result['message_type'],['content'=>$result['data']]));*/
|
||
}
|
||
|
||
public function onClose($server, $fd) {
|
||
//连接关闭,将用户信息从缓存中移除,并存入聊天日志
|
||
$chat_deal=new ChatCloseService($server,$fd);
|
||
$chat_deal->onClose();
|
||
}
|
||
|
||
public function onStart($server) {
|
||
//清空所有缓存
|
||
$base_keys=['CHAT_USER_FD_MAP','CHAT_USER_FD','CHAT_USER_INFO','CHAT_USER_QUEUE','CHAT_CS_FD_MAP','CHAT_CS_FD','CHAT_CS_INFO','CUSTOMER_ONLINE_QUEUE','CHAT_ADMIN_FD_MAP','CHAT_ADMIN_FD','CHAT_ADMIN_INFO'];
|
||
$chat_list=RedisCache::keys('CHAT_DATA_*');
|
||
$offline_chat_list=RedisCache::keys('OFFLINE_CHAT_DATA_*');
|
||
RedisCache::batch_del(array_merge($base_keys,$chat_list,$offline_chat_list));
|
||
|
||
Log::info('主进程清除缓存结束');
|
||
|
||
//定时刷下数据链接,试试看有没有效果。实际有效果,但有个pipe的问题,因为主进程和工作进程之间实际并没有共享数据库实例,尝试在工作进程中开定时器刷新,以防broken pipe的情况出现
|
||
/*swoole_timer_tick(1000*600, function () {
|
||
Db::name('users')->where(['user_id'=>0])->value('user_id');
|
||
});*/
|
||
}
|
||
|
||
public function onWorkerStart($server,$worker_id) {
|
||
//定时刷下数据链接,试试看有没有效果。由于8个进程都会刷新,减少刷新频率,30分钟刷一次,试下TP的自动重连机制,暂不刷新
|
||
/*swoole_timer_tick(1000*1800, function () {
|
||
Db::name('users')->where(['user_id'=>0])->value('user_id');
|
||
});*/
|
||
|
||
if ($server->taskworker) {
|
||
Log::info('启动消息队列监听任务进程'.$worker_id);
|
||
//每个任务进程起一个监听,尝试监听redis,以便实现消息通知
|
||
while (true) {
|
||
if (($msgs = RedisCache::brpop('MESSAGE_QUEUE', 5))==null) {
|
||
//没有则继续监听
|
||
continue;
|
||
} else {
|
||
$message_queue_deal=new MessageQueueService($server,$msgs);
|
||
$message_queue_deal->deal();
|
||
}
|
||
}
|
||
} else {
|
||
Log::info('启动通话处理任务进程'.$worker_id);
|
||
}
|
||
}
|
||
|
||
public function onTask($server,$task_id,$src_worker_id,$data) {
|
||
//暂不使用
|
||
}
|
||
public function onFinish($server,$task_id,$data) {
|
||
//暂不使用
|
||
}
|
||
}
|