@@ -9,12 +9,11 @@ use think\Db;
use think\facade\Log ;
use WebSocket\Client ;
use think\facade\Env ;
use app\api\model\WechatFriendModel as WechatFriend ;
use app\api\model\WechatFriendModel as WechatFriend ;
use app\api\model\WechatMomentsModel as WechatMoments ;
use think\facade\Cache ;
class WebSocketController extends BaseController
{
protected $authorized ;
@@ -27,7 +26,7 @@ class WebSocketController extends BaseController
/************************************
* 初始化相关功能
************************************/
/**
* 构造函数 - 初始化WebSocket连接
* @param array $userData 用户数据
@@ -44,39 +43,39 @@ class WebSocketController extends BaseController
*/
protected function initConnection ( $userData = [])
{
if ( ! empty ( $userData ) && count ( $userData )){
if ( ! empty ( $userData ) && count ( $userData )) {
if ( empty ( $userData [ 'userName' ]) || empty ( $userData [ 'password' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
}
// 检查缓存中是否存在有效的token
$cacheKey = 'websocket_token_' . $userData [ 'userName' ];
$cachedToken = Cache :: get ( $cacheKey );
$cachedToken = Cache :: get ( $cacheKey );
if ( $cachedToken ) {
$this -> authorized = $cachedToken ;
$this -> accountId = $userData [ 'accountId' ];
} else {
$params = [
'grant_type' => 'password' ,
'username' => $userData [ 'userName' ],
'password' => $userData [ 'password' ]
];
$params = [
'grant_type' => 'password' ,
'username' => $userData [ 'userName' ],
'password' => $userData [ 'password' ]
];
// 调用登录接口获取token
$headerData = [ 'client:kefu-client' ];
$header = setHeader ( $headerData , '' , 'plain' );
$result = requestCurl ( 'https://kf.quwanzhi.com:9991/token' , $params , 'POST' , $header );
$result_array = handleApiResponse ( $result );
// 调用登录接口获取token
$headerData = [ 'client:kefu-client' ];
$header = setHeader ( $headerData , '' , 'plain' );
$result = requestCurl ( 'https://kf.quwanzhi.com:9991/token' , $params , 'POST' , $header );
$result_array = handleApiResponse ( $result );
if ( isset ( $result_array [ 'access_token' ]) && ! empty ( $result_array [ 'access_token' ])) {
$this -> authorized = $result_array [ 'access_token' ];
$this -> accountId = $userData [ 'accountId' ];
// 将token存入缓存, 有效期5分钟
Cache :: set ( $cacheKey , $this -> authorized , 300 );
} else {
return json_encode ([ 'code' => 400 , 'msg' => '获取系统授权信息失败' ]);
if ( isset ( $result_array [ 'access_token' ]) && ! empty ( $result_array [ 'access_token' ])) {
$this -> authorized = $result_array [ 'access_token' ];
$this -> accountId = $userData [ 'accountId' ];
// 将token存入缓存, 有效期5分钟
Cache :: set ( $cacheKey , $this -> authorized , 300 );
} else {
return json_encode ([ 'code' => 400 , 'msg' => '获取系统授权信息失败' ]);
}
}
} else {
@@ -85,7 +84,7 @@ class WebSocketController extends BaseController
}
if ( empty ( $this -> authorized ) || empty ( $this -> accountId )) {
return json_encode ([ 'code' => 400 , 'msg' => '缺失关键参数' ]);
return json_encode ([ 'code' => 400 , 'msg' => '缺失关键参数' ]);
}
$this -> connect ();
@@ -97,40 +96,40 @@ class WebSocketController extends BaseController
protected function connect ()
{
try {
//证书
$context = stream_context_create ();
stream_context_set_option ( $context , 'ssl' , 'verify_peer' , false );
stream_context_set_option ( $context , 'ssl' , 'verify_peer_name' , false );
//开启WS链接
$result = [
" accessToken " => $this -> authorized ,
" accountId " => $this -> accountId ,
" client " => " kefu-client " ,
" cmdType " => " CmdSignIn " ,
" seq " => 1 ,
];
//证书
$context = stream_context_create ();
stream_context_set_option ( $context , 'ssl' , 'verify_peer' , false );
stream_context_set_option ( $context , 'ssl' , 'verify_peer_name' , false );
$content = json_encode ( $result );
$this -> client = new Client ( " wss://kf.quwanzhi.com:9993 " ,
[
'filter' => [ 'text' , 'binary' , 'ping' , 'pong' , 'close' , 'receive' , 'send' ] ,
'context' => $context ,
'headers' => [
'Sec-WebSocket-Protocol' => 'soap' ,
'origin' => 'localhost' ,
],
'timeout' => 86400 ,
]
);
$this -> client -> send ( $conten t );
//开启WS链接
$result = [
" accessToken " => $this -> authorized ,
" accountId " => $this -> accountId ,
" client " => " kefu-client " ,
" cmdType " => " CmdSignIn " ,
" seq " => 1 ,
];
$content = json_encode ( $result );
$this -> client = new Client ( " wss://kf.quwanzhi.com:9993 " ,
[
'filter' => [ 'text' , 'binary' , 'ping' , 'pong' , 'close' , 'receive' , 'send' ],
'context' => $contex t ,
'headers' => [
'Sec-WebSocket-Protocol' => 'soap' ,
'origin' => 'localhost' ,
],
'timeout' => 86400 ,
]
);
$this -> client -> send ( $content );
$this -> isConnected = true ;
$this -> lastHeartbeatTime = time ();
// 启动心跳检测
//$this->startHeartbeat();
} catch ( \Exception $e ) {
Log :: error ( " WebSocket连接失败: " . $e -> getMessage ());
$this -> isConnected = false ;
@@ -143,7 +142,7 @@ class WebSocketController extends BaseController
protected function startHeartbeat ()
{
// 使用定时器发送心跳
\Swoole\Timer :: tick ( $this -> heartbeatInterval * 1000 , function () {
\Swoole\Timer :: tick ( $this -> heartbeatInterval * 1000 , function () {
if ( $this -> isConnected ) {
$this -> sendHeartbeat ();
}
@@ -160,10 +159,10 @@ class WebSocketController extends BaseController
" cmdType " => " CmdHeartbeat " ,
" seq " => time ()
];
$this -> client -> send ( json_encode ( $heartbeat ));
$this -> lastHeartbeatTime = time ();
} catch ( \Exception $e ) {
Log :: error ( " 发送心跳包失败: " . $e -> getMessage ());
$this -> reconnect ();
@@ -204,7 +203,7 @@ class WebSocketController extends BaseController
protected function sendMessage ( $data )
{
$this -> checkConnection ();
try {
$this -> client -> send ( json_encode ( $data ));
$response = $this -> client -> receive ();
@@ -235,9 +234,9 @@ class WebSocketController extends BaseController
$currentPage = 1 ; // 当前页码
$allMoments = []; // 存储所有朋友圈数据
//过滤消息
//过滤消息
if ( empty ( $wechatAccountId )) {
return json_encode ([ 'code' => 400 , 'msg' => '指定账号不能为空' ]);
return json_encode ([ 'code' => 400 , 'msg' => '指定账号不能为空' ]);
}
try {
@@ -263,21 +262,21 @@ class WebSocketController extends BaseController
sleep ( 10 );
continue ;
}
// 检查返回结果
if ( ! isset ( $message [ 'result' ]) || empty ( $message [ 'result' ]) || ! is_array ( $message [ 'result' ])) {
break ;
}
// 检查是否遇到旧数据
$hasOldData = false ;
foreach ( $message [ 'result' ] as $moment ) {
$momentId = WechatMoments :: where ( 'snsId' , $moment [ 'snsId' ])
-> where ( 'wechatAccountId' , $wechatAccountId )
-> value ( 'id' );
if ( ! empty ( $momentId )) {
$hasOldData = true ;
break ;
@@ -330,31 +329,31 @@ class WebSocketController extends BaseController
return json_encode ( $result );
} catch ( \Exception $e ) {
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
}
}
/**
/**
* 朋友圈点赞
* @return \think\response\Json
*/
public function momentInteract ( $data = [])
{
$snsId = ! empty ( $data [ 'snsId' ]) ? $data [ 'snsId' ] : '' ;
$wechatAccountId = ! empty ( $data [ 'wechatAccountId' ]) ? $data [ 'wechatAccountId' ] : '' ;
$wechatFriendId = ! empty ( $data [ 'wechatFriendId' ]) ? $data [ 'wechatFriendId' ] : 0 ;
//过滤消息
if ( empty ( $snsId )) {
return json_encode ([ 'code' => 400 , 'msg' => 'snsId不能为空' ]);
if ( empty ( $snsId )) {
return json_encode ([ 'code' => 400 , 'msg' => 'snsId不能为空' ]);
}
if ( empty ( $wechatAccountId )) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
if ( empty ( $wechatAccountId )) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
}
try {
try {
$result = [
" cmdType " => " CmdMomentInteract " ,
" momentInteractType " => 1 ,
@@ -362,16 +361,16 @@ class WebSocketController extends BaseController
" snsId " => $snsId ,
" wechatAccountId " => $wechatAccountId ,
" wechatFriendId " => $wechatFriendId ,
];
];
$message = $this -> sendMessage ( $result );
return json_encode ([ 'code' => 200 , 'msg' => '点赞成功' , 'data' => $message ]);
} catch ( \Exception $e ) {
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
return json_encode ([ 'code' => 200 , 'msg' => '点赞成功' , 'data' => $message ]);
} catch ( \Exception $e ) {
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
}
}
/**
/**
* 朋友圈取消点赞
* @return \think\response\Json
*/
@@ -381,36 +380,36 @@ class WebSocketController extends BaseController
$data = $this -> request -> param ();
if ( empty ( $data )) {
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
}
//过滤消息
if ( empty ( $data [ 'snsId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => 'snsId不能为空' ]);
return json_encode ([ 'code' => 400 , 'msg' => 'snsId不能为空' ]);
}
if ( empty ( $data [ 'wechatAccountId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
}
try {
$result = [
" CommentId2 " => '' ,
" CommentTime " => 0 ,
" cmdType " => " CmdMomentCancelInteract " ,
" optType " => 1 ,
" seq " => time (),
" snsId " => $data [ 'snsId' ],
" wechatAccountId " => $data [ 'wechatAccountId' ],
" wechatFriendId " => 0 ,
];
$result = [
" CommentId2 " => '' ,
" CommentTime " => 0 ,
" cmdType " => " CmdMomentCancelInteract " ,
" optType " => 1 ,
" seq " => time (),
" snsId " => $data [ 'snsId' ],
" wechatAccountId " => $data [ 'wechatAccountId' ],
" wechatFriendId " => 0 ,
];
$message = $this -> sendMessage ( $result );
return json_encode ([ 'code' => 200 , 'msg' => '取消点赞成功' , 'data' => $message ]);
return json_encode ([ 'code' => 200 , 'msg' => '取消点赞成功' , 'data' => $message ]);
} catch ( \Exception $e ) {
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
return json_encode ([ 'code' => 500 , 'msg' => $e -> getMessage ()]);
}
} else {
return json_encode ([ 'code' => 400 , 'msg' => '非法请求' ]);
return json_encode ([ 'code' => 400 , 'msg' => '非法请求' ]);
}
}
@@ -462,19 +461,19 @@ class WebSocketController extends BaseController
// 发送请求
$this -> client -> send ( json_encode ( $params ));
// 接收响应
$response = $this -> client -> receive ();
$message = json_decode ( $response , true );
if ( empty ( $message )){
return json_encode ([ 'code' => 500 , 'msg' => '获取朋友圈资源链接失败' ]);
if ( empty ( $message )) {
return json_encode ([ 'code' => 500 , 'msg' => '获取朋友圈资源链接失败' ]);
}
if ( $message [ 'cmdType' ] == 'CmdDownloadMomentImagesResult' && is_array ( $message [ 'urls' ]) && count ( $message [ 'urls' ]) > 0 ){
$urls = json_encode ( $message [ 'urls' ], 256 );
Db :: table ( 's2_wechat_moments' ) -> where ( 'snsId' , $data [ 'snsId' ]) -> update ([ 'resUrls' => $urls ]);
if ( $message [ 'cmdType' ] == 'CmdDownloadMomentImagesResult' && is_array ( $message [ 'urls' ]) && count ( $message [ 'urls' ]) > 0 ) {
$urls = json_encode ( $message [ 'urls' ], 256 );
Db :: table ( 's2_wechat_moments' ) -> where ( 'snsId' , $data [ 'snsId' ]) -> update ([ 'resUrls' => $urls ]);
}
return json_encode ([ 'code' => 200 , 'msg' => '获取朋友圈资源链接成功' , 'data' => $message ]);
return json_encode ([ 'code' => 200 , 'msg' => '获取朋友圈资源链接成功' , 'data' => $message ]);
} catch ( \Exception $e ) {
// 记录错误日志
Log :: error ( '获取朋友圈资源链接异常:' . $e -> getMessage ());
@@ -507,19 +506,18 @@ class WebSocketController extends BaseController
return false ;
}
try {
foreach ( $momentList as $moment ) {
// 提取momentEntity中的数据
$momentEntity = $moment [ 'momentEntity' ] ? ? [];
// 检查朋友圈数据是否已存在
$momentId = WechatMoments :: where ( 'snsId' , $moment [ 'snsId' ])
-> where ( 'wechatAccountId' , $wechatAccountId )
-> value ( 'id' );
$dataToSave = [
'commentList' => json_encode ( $moment [ 'commentList' ] ? ? [], 256 ),
'createTime' => $moment [ 'createTime' ] ? ? 0 ,
@@ -543,7 +541,7 @@ class WebSocketController extends BaseController
// 如果已存在,则更新数据
Db :: table ( 's2_wechat_moments' ) -> where ( 'id' , $momentId ) -> update ( $dataToSave );
} else {
if ( empty ( $wechatFriendId )){
if ( empty ( $wechatFriendId )) {
$wechatFriendId = WechatFriend :: where ( 'wechatAccountId' , $wechatAccountId ) -> where ( 'wechatId' , $momentEntity [ 'userName' ]) -> value ( 'id' );
}
// 如果不存在,则插入新数据
@@ -588,7 +586,7 @@ class WebSocketController extends BaseController
if ( empty ( $wechatFriendId )) {
return json_encode ([ 'code' => 400 , 'msg' => '好友ID不能为空' ]);
}
if ( empty ( $wechatAccountId )) {
return json_encode ([ 'code' => 400 , 'msg' => '微信账号ID不能为空' ]);
}
@@ -609,7 +607,7 @@ class WebSocketController extends BaseController
// 发送请求并获取响应
$message = $this -> sendMessage ( $params );
// 记录日志
Log :: info ( '修改好友标签:' . json_encode ( $params , 256 ));
Log :: info ( '修改好友标签结果:' . json_encode ( $message , 256 ));
@@ -619,7 +617,7 @@ class WebSocketController extends BaseController
} catch ( \Exception $e ) {
// 记录错误日志
Log :: error ( '修改好友标签失败:' . $e -> getMessage ());
// 返回错误响应
return json_encode ([ 'code' => 500 , 'msg' => '修改标签失败:' . $e -> getMessage ()]);
}
@@ -653,24 +651,23 @@ class WebSocketController extends BaseController
// 消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包( gif、其他表情包) 49:小程序/其他:图文、文件)
// 当前, type 为文本、图片、动图表情包的时候, content为string, 其他情况为对象 {type: 'file/link/...', url: '', title: '', thunmbPath: '', desc: ''}
$params = [
" cmdType " => " CmdSendMessage " ,
" content " => $dataArray [ 'content' ],
" msgSubType " => 0 ,
" msgType " => $dataArray [ 'msgType' ],
" seq " => time (),
" wechatAccountId " => $dataArray [ 'wechatAccountId' ],
" wechatChatroomId " => 0 ,
" wechatFriendId " => $dataArray [ 'wechatFriendId' ],
];
" cmdType " => " CmdSendMessage " ,
" content " => $dataArray [ 'content' ],
" msgSubType " => 0 ,
" msgType " => $dataArray [ 'msgType' ],
" seq " => time (),
" wechatAccountId " => $dataArray [ 'wechatAccountId' ],
" wechatChatroomId " => 0 ,
" wechatFriendId " => $dataArray [ 'wechatFriendId' ],
];
// 发送请求
$this -> client -> send ( json_encode ( $params ));
// 接收响应
$response = $this -> client -> receive ();
$message = json_decode ( $response , true );
if ( ! empty ( $message )){
return json_encode ([ 'code' => 500 , 'msg' => '信息发送成功' , 'data' => $message ]);
if ( ! empty ( $message )) {
return json_encode ([ 'code' => 200 , 'msg' => '信息发送成功' , 'data' => $message ]);
}
}
@@ -678,65 +675,55 @@ class WebSocketController extends BaseController
* 发送群消息
* @return \think\response\Json
*/
public function sendCommunity ()
public function sendCommunity ($dataArray = [] )
{
if ( $this -> request -> isPost ( )) {
$data = $this -> request -> post ( );
if ( empty ( $data )) {
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
}
$dataArray = $data ;
if ( ! is_array ( $dataArray )) {
return json_encode ([ 'code' => 400 , 'msg' => '数据格式错误' ]);
}
//过滤消息
if ( empty ( $dataArray [ 'content' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '内容缺失' ]);
}
if ( empty ( $dataArray [ 'wechatAccountId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
}
if ( empty ( $dataArray [ 'msgType' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '类型缺失' ]);
}
if ( empty ( $dataArray [ 'wechatChatroomId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '群id不能为空' ]);
}
$msg = '消息成功发送' ;
$message = [];
try {
//消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包 49:小程序)
$result = [
" cmdType " => " CmdSendMessage " ,
" content " => htmlspecialchars_decode ( $dataArray [ 'content' ]),
" msgSubType " => 0 ,
" msgType " => $dataArray [ 'msgType' ],
" seq " => time (),
" wechatAccountId " => $dataArray [ 'wechatAccountId' ],
" wechatChatroomId " => $dataArray [ 'wechatChatroomId' ],
" wechatFriendId " => 0 ,
];
$result = json_encode ( $result );
$this -> client -> send ( $result );
$message = $this -> client -> receive ();
//关闭WS链接
$this -> client -> close ();
//Log::write('WS群消息发送');
//Log::write($message);
$message = json_decode ( $message , 1 );
} catch ( \Exception $e ) {
$msg = $e -> getMessage ();
}
return json_encode ([ 'code' => 200 , 'msg' => $msg , 'data' => $message ]);
} else {
return json_encode ([ 'code' => 400 , 'msg' => '非法请求' ]);
//return errorJson('非法请求');
if ( ! is_array ( $dataArray )) {
return json_encode ([ 'code' => 400 , 'msg' => '数据格式错误' ] );
}
//过滤消息
if ( empty ( $dataArray [ 'content' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '内容缺失' ]);
}
if ( empty ( $dataArray [ 'wechatAccountId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
}
if ( empty ( $dataArray [ 'msgType' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '类型缺失' ]);
}
if ( empty ( $dataArray [ 'wechatChatroomId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '群id不能为空' ]);
}
$message = [];
try {
//消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包 49:小程序)
$params = [
" cmdType " => " CmdSendMessage " ,
" content " => htmlspecialchars_decode ( $dataArray [ 'content' ]),
" msgSubType " => 0 ,
" msgType " => $dataArray [ 'msgType' ],
" seq " => time (),
" wechatAccountId " => $dataArray [ 'wechatAccountId' ],
" wechatChatroomId " => $dataArray [ 'wechatChatroomId' ],
" wechatFriendId " => 0 ,
];
// 发送请求
$this -> client -> send ( json_encode ( $params ));
// 接收响应
$response = $this -> client -> receive ();
$message = json_decode ( $response , true );
if ( ! empty ( $message )) {
return json_encode ([ 'code' => 200 , 'msg' => '信息发送成功' , 'data' => $message ]);
}
} catch ( \Exception $e ) {
$msg = $e -> getMessage ();
return json_encode ([ 'code' => 400 , 'msg' => $msg , 'data' => $message ]);
}
}
/**
@@ -747,26 +734,26 @@ class WebSocketController extends BaseController
public function sendCommunitys ( $data = [])
{
if ( empty ( $data )) {
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
return json_encode ([ 'code' => 400 , 'msg' => '参数缺失' ]);
}
$dataArray = $data ;
if ( ! is_array ( $dataArray )) {
return json_encode ([ 'code' => 400 , 'msg' => '数据格式错误' ]);
return json_encode ([ 'code' => 400 , 'msg' => '数据格式错误' ]);
}
//过滤消息
if ( empty ( $dataArray [ 'content' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '内容缺失' ]);
return json_encode ([ 'code' => 400 , 'msg' => '内容缺失' ]);
}
if ( empty ( $dataArray [ 'wechatAccountId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
return json_encode ([ 'code' => 400 , 'msg' => '微信id不能为空' ]);
}
if ( empty ( $dataArray [ 'msgType' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '类型缺失' ]);
return json_encode ([ 'code' => 400 , 'msg' => '类型缺失' ]);
}
if ( empty ( $dataArray [ 'wechatChatroomId' ])) {
return json_encode ([ 'code' => 400 , 'msg' => '群id不能为空' ]);
return json_encode ([ 'code' => 400 , 'msg' => '群id不能为空' ]);
}
$msg = '消息成功发送' ;
@@ -796,11 +783,10 @@ class WebSocketController extends BaseController
$msg = $e -> getMessage ();
}
return json_encode ([ 'code' => 200 , 'msg' => $msg , 'data' => $message ]);
return json_encode ([ 'code' => 200 , 'msg' => $msg , 'data' => $message ]);
}
/**
* 邀请好友入群
* @param array $data 请求参数
@@ -843,11 +829,11 @@ class WebSocketController extends BaseController
Log :: info ( '邀请好友入群请求:' . json_encode ( $params , 256 ));
$message = $this -> sendMessage ( $params );
return json_encode ([ 'code' => 200 , 'msg' => '邀请成功' , 'data' => $message ]);
return json_encode ([ 'code' => 200 , 'msg' => '邀请成功' , 'data' => $message ]);
} catch ( \Exception $e ) {
// 记录错误日志
Log :: error ( '邀请好友入群异常:' . $e -> getMessage ());
// 返回错误响应
// 返回错误响应
return json_encode ([ 'code' => 500 , 'msg' => '邀请好友入群异常:' . $e -> getMessage ()]);
}
}