初始化代码

This commit is contained in:
2025-12-22 14:32:54 +08:00
parent e27ab90d9f
commit d02b31a8b9
1459 changed files with 240973 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | Longbing [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright Chengdu longbing Technology Co., Ltd.
// +----------------------------------------------------------------------
// | Website http://longbing.org/
// +----------------------------------------------------------------------
// | Sales manager: +86-13558882532 / +86-13330887474
// | Technical support: +86-15680635005
// | After-sale service: +86-17361005938
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\im\controller;
class BaseMessage
{
/**
* @param $server
* @param $client_id
* @param $action
* @param bool $status
* @param string $message
* @param array $data
* @功能说明:发送消息方式
* @author jingshuixian
* @DataTime: 2020/1/13 13:53
*/
public function sendServerMsg($server, $client_id , $action , $status = true, $message = '' , $data = []){
$dataStr = json_encode(
[
'action' => $action ,
'status' => $status ,
'message'=> $message ,
'data' => $data,
'time' => time()
]
);
$server->push($client_id , $dataStr) ;
}
}

178
app/im/controller/Car.php Normal file
View File

@@ -0,0 +1,178 @@
<?php
//include 'crc.php';
//include 'net.php';
//打印十六进制(可以不用)
function println($bytes) {
for($i=0;$i<count($bytes);$i++)
{
printf("%02X ", $bytes[$i]);
}
printf(".");
}
//这里开始
//$net = new net();
$socket = listen('0.0.0.0', 50000);
while(true) {
$cs = accept($socket);
printf($cs);
while($cs) {
try{
$ret = recv_bytes($cs, 1024);
abc($ret);
//println($ret);
}
catch (Exception $e)
{
close();
printf('cs close');
break;
}
}
}
close();
function listen($ip, $port)
{
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $ip, $port);
$ex = socket_listen($socket, 4);
//socket_bind($this->socket, '127.0.0.1', $port) or die("socket_bind() fail:" . socket_strerror(socket_last_error()) . "/n");
//$ex = socket_listen($this->socket, 4) or die("socket_listen() fail:" . socket_strerror(socket_last_error()) . "/n");
// return $ex;
return $socket;
}
//abc处理读取到的卡4字节
function abc($ret)
{
$len = $ret[4];
if($len < 14)
{
//printf('无效数据');
return ;
}
//
$count = $ret[9];
$count = ($count - 3) / 4;
//
for($i=0; $i<$count; $i++)
{
$idx = 10 + ($i * 4);
$card = sprintf("%02X%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2], $ret[$idx+3]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了
$card = sprintf("%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了
printf('card['.$i.']>>'.$card.' | ');
// $post_data['data'] = 'card['.$i.']>>'.$card.' | ';
$card_id = $card;
$card = 'card['.$i.']>>'.$card.' | ';
$url = 'https://car.cncnconnect.com/massage/admin/Tcp/getInfo?card_id='.$card_id.'&time='.msectime();
$a = file_get_contents($url);
// printf(json_encode($a));
}
}
function msectime() {
list($msec,$sec) = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
return $msectime;
}
function crulGetData($url, $post, $method, $header=1){
// $this->_errno = NULL;
// $this->_error = NULL;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if($post != NULL)
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch, CURLOPT_AUTOREFERER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
if($header)
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: application/json',
)
);
$result = curl_exec($ch);
return $result;
}
function accept($socket)
{
return socket_accept($socket);
}
function close()
{
if($this->socket == 0) return;
socket_close($this->socket);
$this->socket = 0;
}
function recv_bytes($cs, $len = 1024)
{
$ret = recv($cs, $len);
$bytes = string_to_bytes($ret);
return $bytes;
}
function recv($cs, $len = 1024)
{
$ret = socket_read($cs, $len) or die("/n");
return $ret;
}
function string_to_bytes($str)
{
$bytes = array();
for($i=0; $i<strlen($str); $i++)
{
$bytes[] = ord($str[$i]);
}
return $bytes;
}
?>

624
app/im/controller/Im.php Normal file
View File

@@ -0,0 +1,624 @@
<?php
namespace app\im\controller;
use app\ApiRest;
use app\Common\service\LongbingUserInfoService;
use app\im\model\ImMessageFriend;
use app\im\service\ImMessageFriendService;
use app\im\service\ImService;
use longbingcore\tools\LongbingDefault;
use longbingcore\tools\LongbingTime;
use think\App;
use think\Request;
use app\im\model\ImChart;
use app\im\model\ImChat;
use app\im\model\ImMessage;
use app\im\model\ImUser;
use app\im\model\ImMyReply;
use app\im\model\ImReplyType;
use app\card\model\UserInfo;
use app\card\model\UserPhone;
use app\im\model\ImClient;
class Im extends ApiRest
{
public $user_id = null;
public $user = null;
public function __construct(App $app) {
parent::__construct($app);
$this->user_id = $this->getUserId();
$this->user = $this->getUserInfo();
}
//获取客户列表
public function listCustomer()
{
//获取参数列表
$param = $this->_param;
//获取用户列表
$user_id = $this->user_id;
//判断用户是否存在
if(empty($user_id)) return $this->error('not login ,please login again.');
//生成分页信息
$page_config = array(
'page' => 1,
'page_count' => 10
);
//获取分页信息
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
//生成查询模型
$chat_model = new ImChat();
//生成消息查询模型
$message_model = new ImMessage();
//生成用户查询模型
// $user_model = new ImUser();
//生成查询
$page_config['total'] = $chat_model->listChatCount($user_id ,$this->_uniacid );
$chats = $chat_model->listChat($user_id ,$this->_uniacid ,$page_config);
$data = [];
if(!empty($chats))
{
foreach($chats as $key => $value)
{
//获取客户信息
$customer_id = null;
if(!in_array($value['user_id'], [$user_id])) $customer_id = $value['user_id'];
if(!in_array($value['target_id'], [$user_id])) $customer_id = $value['target_id'];
if(empty($customer_id)) continue;
//获取客户信息
// $value['customer'] = $user_model->getUser(['id' => $customer_id]);
$customer = longbingGetUser($customer_id ,$this->_uniacid);
if(!empty($customer['is_staff']))
{
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']))
{
if(!empty($customer_info['avatar'])) {
$customer_info = transImagesOne($customer_info ,['avatar'] ,$this->_uniacid);
}
//是员工 就用员工头像 By.jingshuixian
//if(!empty($customer_info['avatar'])) $customer['avatarUrl'] = $customer_info['avatar'];
}
}
$value['customer'] = $customer;
if(empty($value['customer'])) continue;
//获取最后一条消息
$lastmessage = $message_model->lastMessage(['chat_id' => $value['id']]);
//如果最后一条消息是图片
if(isset($lastmessage['message_type']) && !in_array($lastmessage['message_type'], ['text' ])) $lastmessage['content'] = lang($lastmessage['message_type']);
$value['lastmessage'] = $lastmessage;
//获取未读消息总数
$not_rear_message_count = $message_model->listMessageCount(['chat_id' => $value['id'] ,'user_id' => $customer_id ,'target_id' => $user_id ,'status' => 1]);
//未读消息总数
$value['not_read_message_count'] = $not_rear_message_count;
//获取时间
if(isset($value['update_time']) && !empty($value['update_time'])) $value['time'] = date('Y-m-d H:i:s', $value['update_time']);
//判断用户是否存在头像
if(!isset($value['customer']['avatarUrl']) || empty($value['customer']['avatarUrl'])) $value['customer']['avatarUrl'] = $this->defaultImage['avatar'];
//判断客户是否是员工
if(isset($value['customer']['is_staff']) && !empty($value['customer']['is_staff']))
{
//获取员工信息
$user_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
if(isset($user_info['is_staff']) && !empty($user_info['is_staff']) && isset($user_info['name']) && !empty($user_info['name'])){
$value['customer']['nickName'] = $user_info['name'];
}
}
$data[] = $value;
}
}
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
$result = $page_config;
$result['data'] = $data;
//总计未读数
$result['unReadMessageCount'] = ImService::getUnReadMessageCount($this->user_id);
//数据处理
return $this->success($result);
}
/**
* @author jingshuixian
* @DataTime: 2020/1/16 15:58
* @功能说明:新版获取用户列表信息
*/
public function listCustomerV2(){
//获取参数列表
$param = $this->_param;
//获取用户列表
$user_id = $this->user_id;
//判断用户是否存在
if(empty($user_id)) return $this->error('not login ,please login again.');
//初始化朋友列表,兼容老数据
ImMessageFriendService::initOldFriendList($this->_uniacid , $user_id) ;
$result = ImMessageFriendService::getFriendList($this->_uniacid , $user_id , $param['page_count'] ) ;
//总计未读数
$result['unReadMessageCount'] = ImService::getUnReadMessageCount($this->user_id);
//数据处理
return $this->success($result);
}
//获取未读消息列表
public function listNotReadMessage()
{
//获取参数
$param = $this->_param;
$user_id = $this->user_id;
if(!isset($param['chat_id']) || !isset($param['target_id'])) return $this->error(lang('not chat id ,please check param'));
if(isset($param['target_id']) && !isset($param['chat_id']) && !empty($param['target_id']))
{
//获取chat数据
$chat = longbingGetChat($user_id ,$param['target_id'] ,$this->_uniacid);
if(isset($chat['id'])) $param['chat_id'] = $chat['id'];
}
//判断chat_id参数是否存在
if(!isset($param['chat_id'])) return $this->error('not chat id ,please check param');
//if(!isset($param['user_id'])) return $this->error('not user id ,please check param');
$chat_id = $param['chat_id'];
//获取客户关系
$chat = longbingGetChatById($chat_id ,$this->_uniacid);
//判断数据是否存在
if(empty($chat)) return $this->error('not the chat ,please check chat id');
$customer_id = $chat['user_id'];
if(in_array($customer_id, [$this->user_id])) $customer_id = $chat['target_id'];
$user_id = $this->user_id;
//生成查询模型
$message_model = new ImMessage();
//查询数据
$messages = $message_model->listNotReadMessage(['chat_id' => $chat_id ,'target_id' => $user_id]);
$result['data'] = [];
if(!empty($page_config['total'])){
foreach($messages as $key => $val)
{
if(isset($val['create_time']) && !empty($val['create_time'])) $val['time'] = date('Y-m-d H:i:s', $val['create_time']);
$result['data'][] = $val;
}
}
if(isset($this->user['qr_path'])) $this->user = transImagesOne ( $this->user, ['qr_path'] );
$result['user'] = $this->user;
$customer = getUser($customer_id ,$this->_uniacid);
if(isset($customer['qr_path'])) $customer = transImagesOne ( $customer, ['qr_path'] );
$result['customer'] = $customer;
return $this->success($result);
}
//获取消息列表
public function listMessage()
{
$user = longbingGetUser($this->user_id ,$this->_uniacid);
//获取参数
$param = $this->_param;
$chat_id = null;
$customer_id = null;
$chat = null;
//判断参数是否存在
if(isset($param['chat_id'])) $chat_id = $param['chat_id'];
if(isset($param['customer_id'])) $customer_id = $param['customer_id'];
if(empty($chat_id) && empty($customer_id)) $this->error(lang('not customer id,please check param'));
//参数处理(兼容处理)
$result = [];
if(!empty($chat_id))
{
$chat = longbingGetChatById($chat_id ,$this->_uniacid);
}
else{
$chat = longbingGetChat($this->user_id ,$customer_id ,$this->_uniacid ,true);
}
//生成分页信息
$page_config = array(
'page' => 1,
'page_count' => 20
);
//获取分页信息
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
if(!empty($chat))
{
$customer_id = $chat['user_id'];
if(empty($chat_id)) $chat_id = $chat['chat_id'];
if(in_array($customer_id, [$this->user_id])) $customer_id = $chat['target_id'];
//生成消息查询模型
$message_model = new ImMessage();
//获取查询总数
$page_config['total'] = $message_model->listMessageCount(['chat_id' => $chat_id]);
//生成分页数据
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
//生成返回数据
}else{
$page_config['total'] = 0;
$page_config['total_page'] = 0;
}
$result = $page_config;
$result['data'] = [];
//获取客户信息
$customer = longbingGetUser($customer_id ,$this->_uniacid);
if(empty($customer)) return $this->error(lang('user not exist.'));
//获取头像
if(isset($customer['avatarUrl'])) {
$customer = transImagesOne ( $customer, ['avatarUrl'] ,$this->_uniacid);
}else{
$customer['avatarUrl'] = $this->defaultImage['avatarUrl'];
}
//判断客户是否是员工
if(!empty($customer['is_staff']))
{
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']))
{
if(!empty($customer_info['avatar'])) {
$customer_info = transImagesOne($customer_info ,['avatar'] ,$this->_uniacid);
}
if(!empty($customer_info['avatar'])) $customer['avatarUrl'] = $customer_info['avatar'];
}
}
//获取客户电话号码和微信号码
$customer['wechat'] = null;
$phone = null;
$user_info_model = new UserInfo();
//获取微信和电话号码
$user_info = $user_info_model->getUserPhone($customer_id ,$this->_uniacid);
if(isset($user_info['phone']) && !empty($user_info['phone'])) $phone = $user_info['phone'];
if(isset($user_info['wechat']) && !empty($user_info['wechat'])) $customer['wechat'] = $user_info['wechat'];
if(empty($phone)){
$user_phone_model = new UserPhone();
$user_phone = $user_phone_model->getUserPhone($customer_id ,$this->_uniacid);
if(isset($user_phone['phone']) && !empty($user_phone['phone'])) $phone = $user_phone['phone'];
}
//判断聊天者是否是客户
$customer['is_customer'] = false;
$collection_model = new ImClient();
if(!empty($collection_model->isCustomer($this->user_id , $customer_id ,$this->_uniacid))) $customer['is_customer'] = true;
//判断客户是否是员工
if(isset($customer['is_staff']) && !empty($customer['is_staff']))
{
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']) && isset($customer_info['name']) && !empty($customer_info['name'])){
$customer['nickName'] = $customer_info['name'];
//生成第一条默认返回数据
$result['data'][] = array(
'chat_id' => $chat['id'],
'user_id' => $customer_id,
'target_id' => $this->user_id,
'status' => 2,
'uniacid' => $this->_uniacid,
'message_type' => 'welcome',
'content' => lang('Hello, I am ') . $customer['nickName'] . lang(', May I help you? Please contact me!')
);
}
}
$customer['phone'] = $phone;
if(!empty($page_config['total'])){
$msgwhere[] = ['chat_id','=',$chat_id];
//自己发送的
$msgwhere[] = ['is_show','<>',2];
$msgwhere[] = ['user_id','=',$this->getUserId()];
$msgwhere[] = ['deleted','=',0];
$whereT[] = ['deleted','=',0];
//自己接受的
$whereT[] = ['target_id','=',$this->getUserId()];
$whereT[] = ['target_is_show','<>',2];
$whereT[] = ['chat_id','=',$chat_id];
foreach($message_model->listMessageV2($msgwhere ,$page_config,$whereT) as $key => $val)
{
if(isset($val['create_time']) && !empty($val['create_time'])) $val['time'] = date('Y-m-d H:i:s', $val['create_time']);
$result['data'][] = $val;
}
//dump($this->getUserId(),$chat['user_id'],$msgwhere,$result['data']);exit;
}
// if(isset($this->user['qr_path'])) $this->user = transImagesOne ( $this->user, ['qr_path'] );
//判断用户是否是员工
if(!empty($user['is_staff']))
{
$user_info = longbingGetUserInfo($this->user_id ,$this->_uniacid);
if(isset($user_info['is_staff']) && !empty($user_info['is_staff']))
{
if(!empty($user_info['avatar'])) {
$user_info = transImagesOne($user_info ,['avatar'] ,$this->_uniacid);
}
if(!empty($user_info['avatar'])) $user['avatarUrl'] = $user_info['avatar'];
}
}
//默认头像处理
//没有头像就给一个默认头像
$customer['avatarUrl'] = empty($customer['avatarUrl']) ? LongbingDefault::$avatarImgUrl : $customer['avatarUrl'];
$user['avatarUrl'] = empty($user['avatarUrl']) ? LongbingDefault::$avatarImgUrl : $user['avatarUrl'];
$result['user'] = $user;
$result['customer'] = $customer;
//阅读所有消息
$result['readMessageNumber'] = ImService::readMessage($this->_uniacid ,$this->user_id , $customer_id);
return $this->success($result);
}
//标记已读消息
public function readMessage()
{
$param = $this->_param ;
$message_model = new ImMessage();
$count = 0 ;
if ( isset($param['id']) ) {
$id = $param['id'] ;
$message = $message_model->find($id);
if($message){
ImService::readMessage($this->_uniacid ,$this->user_id , $message['user_id'] ) ;
}
}
return $this->success(['count' => $count ] );
}
//获取常用话术
public function listReply()
{
//获取用户信息
$user_id = $this->user_id;
//生成话术分类查询模型
$reply_type_model = new ImReplyType();
//生成快速回复话术查询模型
$reply_model = new ImMyReply();
//获取自定义话术
$my_replys = $reply_model->listReply(['uniacid' => $this->_uniacid ,'user_id' => $user_id ,'status' => 1]);
$result[] = ['title' => lang('my reply') , 'data' => $my_replys ,'is_myself' => true];
//获取types
$types = $reply_type_model->listAllType(['uniacid' => $this->_uniacid ,'status' => 1]);
foreach($types as $type)
{
$data['title'] = $type['title'];
$data['data'] = $reply_model->listReply(['uniacid' => $this->_uniacid ,'user_id' => 0 ,'status' => 1 ,'type' => $type['id']]);
$data['is_myself'] = false;
$result[] = $data;
}
return $this->success($result);
}
//创建和更新常用话术
public function addReply()
{
//获取参数
$input = $this->_input;
$param = $this->_param;
if(!isset($input['content'])) return $this->error('content is not exist ,please check .');
$is_create = true;
if(isset($input['id']) && !empty($input['id'])) $is_create = false;
//获取用户信息
$user_id = $this->user_id;
//生成快速回复话术查询模型
$my_reply_model = new ImMyReply();
if($is_create)
{
//创建
$result = $my_reply_model->createReply(['uniacid' => $this->_uniacid ,'status' => 1 ,'content' => $input['content'] ,'user_id' => $user_id]);
}else{
//修改
$result = $my_reply_model->updateReply(['id' =>$param['id'] , 'uniacid' => $this->_uniacid ,'user_id' => $user_id] ,['content' => $input['content']]);
}
//获取自定义话术
return $this->success($result);
}
//删除常用话术
public function delReply()
{
$param = $this->_param;
$user_id = $this->user_id;
if(!isset($param['id'])) return $this->error('reoly id is not exist ,please check .');
//生成快速回复话术查询模型
$my_reply_model = new ImMyReply();
//删除话术
$result = $my_reply_model->deleteReply(['id' =>$param['id'] ,'uniacid' => $this->_uniacid ,'user_id' => $user_id]);
return $this->success($result);
}
/**
* 腾讯IM签名
*
* @author shuixian
* @DataTime: 2019/12/10 11:30
*/
public function getTimUserSig(){
//需要远程获取和加密
$sdkappid = 1400288706 ;
$key = 'd31548b81e57bf823e12d240e4cce237e09f666bdff3fc325eb4bc386e62832d' ;
$user_id = $this->_param['user_id'];
$userSig = longbing_publics_tim_genSig($sdkappid , $key , $user_id );
$result = ['user_id'=>$user_id , 'userSig' => $userSig] ;
return $this->success($result);
}
/**
* 保存聊天信息
*
* @return \think\Response
* @author shuixian
* @DataTime: 2019/12/11 9:29
*/
public function sendMessage(){
//获取参数列表
//{type: "text", content: "456789", target_id: 14, uniacid: "8890", user_id: 20} //发消息
//{"action":"getUnReadMessageCount","status":true,"message":"","data":{"count":2}} // 获取未读消息树
$param = $this->_param;
//获取房间ID
$chat_id = ImService::getChatId($this->_uniacid , $this->user_id, $param['target_id']);
//还需要校验参数合法新
$value['message_type'] = $param['message_type'];
$value['chat_id'] = $chat_id;//需要获取和判断
$value['user_id'] = $this->user_id;
$value['target_id'] = $param['target_id']; //需要判断接收用户的合法性
$value['content'] = $param['content'];
$value['status'] = 1;
$value['uniacid'] = $this->_uniacid;
$value['create_time'] = time();
$value['update_time'] = time();
$value['is_show'] = 1;
$result = ImService::addMessage($value);
if($result){
$value['id'] = $result ;
ImService::sendImMessageTmpl($this->_uniacid , $value['user_id'] , $value['target_id']) ;
return $this->success( $value );
}else{
$this->error('');
}
}
/**
* @author jingshuixian
* @DataTime: 2020/1/15 13:13
* @功能说明:获取目标客户发送的消息数量
*/
public function getCustomerUnReadMessageCount(){
$param = $this->_param ;
$user_id = $this->user_id;
$target_id = 0 ;
$count = 0 ;
if (isset($param['target_id'])) {
$target_id = $param['target_id'];
$count = ImService::getUnReadMessageCountByUserIdAndTargetId( $target_id , $user_id);
}
$data[] = ['action'=> 'getCustomerUnReadMessageCount' , 'data' => ['count' => $count, 'user_id' => $user_id , 'target_id' => $target_id ] ] ;
$data[] = ['action' => 'getUnReadMessageCount' , 'data' => ['count' => ImService::getUnReadMessageCount($user_id) ] ] ;
$message_model = new ImMessage();
$messageList = $message_model->where( [ ['user_id' , '=' ,$target_id ] ,[ 'target_id' , '=' , $user_id ] , ['status', '=' , 1]] )->select();
foreach ($messageList as $item ){
$data[] = ['action' => 'getNewMessage' , 'data' => $item ] ;
}
$key = 'message'.$user_id.'-'.$target_id;
//获取撤回消息
$cancel_msg = getCache($key,$this->_uniacid);
$data[] = ['action' => 'getCancelMessage' , 'data' => $cancel_msg ] ;
setCache($key,[],0,$this->_uniacid);
return $this->success( $data ) ;
}
/**
* @author chenniang
* @DataTime: 2021-05-26 17:33
* @功能说明:修改消息状态 1都可见 2删除对方可见 撤回都不可见
*/
public function updateMsgStatus(){
$input = $this->_input;
$message_model = new ImMessage();
$info = $message_model->where(['id'=>$input['id']])->find()->toArray();
//撤回只有送人课操作
if($input['is_show']==-1){
$update['is_show'] = -1;
if($info['target_is_show']==1){
$update['target_is_show'] = -1;
}
}
//删除
if($input['is_show']==2){
//判断我是否是发送者
if($info['user_id']==$this->getUserId()){
$update['is_show'] = 2;
}else{
$update['target_is_show'] = 2;
}
}
$res = $message_model->where(['id'=>$input['id']])->update($update);
$data = $message_model->where(['id'=>$input['id']])->find();
if(!empty($data)){
$data = $data->toArray();
$key = 'message'.$data['target_id'].'-'.$data['user_id'];
setCache($key,$data,0,$this->_uniacid);
}
return $this->success( $res ) ;
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace app\im\controller;
class Index
{
public function index()
{
return '您好!这是一个[im]示例应用';
}
}

View File

@@ -0,0 +1,594 @@
<?php
namespace app\im\controller;
use think\App;
use app\ApiRest;
use app\BaseController;
use app\im\model\ImUser;
use app\im\model\ImChat;
use app\im\model\ImMessage;
use think\Exception;
class MessageHandler
{
protected $connect_name = 'longbing_im_connect_';
protected $chat_name = 'longbing_chat_';
protected $uniacid_wss = 'wss';
// public function __construct ()
// {
//
// }
//登陆
public function login($server ,$client_id ,$data)
{
//获取参数
$value = [];
if(isset($data['data'])) $value = $data['data'];
if(empty($value)) return ;
$user_id = null;
$uniacid = '7777';
if(isset($value['user_id'])) $user_id = $value['user_id'];
if(isset($value['uniacid'])) $uniacid = $value['uniacid'];
if(empty($user_id) || empty($uniacid)) return ;
//获取用户信息
$user = $this->getUser($user_id ,$uniacid);
//判断用户是否存在
if(empty($user)) {
return $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> lang('login error') ,'data' =>[]]));
}
//设置用户连接数据
$user['client_id'] = $client_id;
$cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
//设置用户连接
$cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
//判断缓存是否插入成功
if(empty($cache_user) || empty($cache_connect)) $server->push($client_id ,json_encode(lang('login error')));
//返回登陆成功
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => true ,'message'=> 'login success.' ,'data' =>$user]));
}
//检查登录
public function checkLogin($client_id ,$data = [])
{
$result = false;
//获取连接信息
$connect = $this->getConnect($client_id);
//如果没有登录
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
{
$user_id = null;
$uniacid = '7777';
//判断用户id是否存在
if(!isset($data['user_id'])) return $result;
//获取用户id
$user_id = $data['user_id'];
//获取uniacid
if(isset($data['uniacid'])) $uniacid = $data['uniacid'];
//获取用户数据
$user = $this->getUser($user_id ,$uniacid);
//判断用书是否存在
if(empty($user)) return $result;
//设置用户连接数据
$user['client_id'] = $client_id;
$cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
//设置用户连接
$cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
//判断缓存是否插入成功
if(!empty($cache_user) && !empty($cache_connect)) $result = true;
}else{
$result = true;
}
return $result;
}
//退出
public function logout($client_id)
{
$this->delConnect($client_id);
}
//发送消息
public function sendMessage($server ,$client_id ,$data)
{
//登录检查
if(!$this->checkLogin($client_id ,$data['data'])){
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
return;
}
//获取用户是否登录
$connect = $this->getConnect($client_id);
$user = null;
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
{
return;
}else{
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
}
//判断用户是否存在
if(empty($user)) return ;
//判断连接是否正确
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
{
$user['client_id'] = $client_id;
$this->setCacheUser($connect['user_id'], $user ,'ws');
}
//检查消息
$value['message_type'] = 'text';
$value['status'] = 1;
$value['user_id'] = $connect['user_id'];
$value['uniacid'] = $connect['uniacid'];
$value['create_time'] = time();
if(isset($data['data'])){
$data = $data['data'];
}else{
return;
}
//判断接受者是否存在
if(isset($data['target_id'])) {
$value['target_id'] = $data['target_id'];
}else{
return ;
}
//判断数据类型是否存在
if(isset($data['type'])) $value['message_type'] = $data['type'];
//判断状态是否存在
if(isset($data['status'])) $value['status'] = $data['status'];
//判断发送者是否存在
if(isset($data['user_id'])) $value['user_id'] = $data['user_id'];
//判断uniacid是否存在
if(isset($data['uniacid'])) $value['uniacid'] = $data['uniacid'];
if(isset($data['chat_id']))
{
$value['chat_id'] = $data['chat_id'];
}else{
// $data = $this->getChat($value['user_id'], $value['target_id'] ,$data['uniacid']);
$value['chat_id'] = $this->getChatId($value['user_id'], $value['target_id'] ,$data['uniacid'] ,true);
//$server->push($client_id , json_encode($value ,true));die;
}
//判断发送消息是否存在
if(isset($data['content'])) {
$value['content'] = $data['content'];
}else{
return ;
}
//检查数据(防止伪造数据的存在)
$target = $this->getUser($value['target_id'] ,$value['uniacid']);
//判断用户是否存在
if(empty($target)) return;
//存储数据
// $push_data = array(
// 'action' => 'addMessage',
// 'event' => 'asyncAddMessage',
// 'message' => $value
// );
// $i = 1000000;
// while($i>0)
// {
// publisher(json_encode($push_data ,true));
// $i = $i -1;
// }
// publisher(json_encode($push_data ,true));
$resultAddMsg = false ;
//随机模拟发送消息失败情况
/*mt_srand();
$demoError = mt_rand(0, 1);
if($demoError){
if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);
}*/
if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);
//By.jingshuixian 如果消息存储失败,直接返回
if(!$resultAddMsg){
$server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
return false ;
}
//判断用户是否登录
if(isset($target['client_id'])) {
$value['time'] = date('Y-m-d H:i:s', time());
try{
$server->push($target['client_id'] , json_encode(['action' => 'getNewMessage' ,'status' => $resultAddMsg , 'data' => $value] ,true));
}catch (Exception $e){
//echo "$server->push error" ;
}
//向消息接受者发送未读消息数量
//$this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['target_id' => $data['user_id']]);
$this->getCustomer($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
$this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
$this->getUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
}else{
//发送服务通知
// $push_data = array(
// 'action' => 'sendMessageWxServiceNotice',
// 'event' => 'longbingSendMessageWxServiceNotice',
// 'message' => $value
// );
// publisher(json_encode($push_data ,true));
longbingSendMessageWxServiceNotice($value);
}
$value['status'] = 1;
$value['creat_time'] = time();
$value['time'] = date('Y-m-d H:i:s', time());
$server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
//存储数据
// $push_data = array(
// 'action' => 'addMessage',
// 'event' => 'asyncAddMessage',
// 'message' => $value
// );
// publisher(json_encode($push_data ,true) ,1000);
//发送用户总的未读数据获取用户
}
//获取用户缓存
function getCacheUser($user_id ,$uniacid = '7777')
{
$key = 'longbing_ws_card_user_' . $user_id;
if(!hasCache($key ,$uniacid)) return null;
return getCache($key ,$uniacid);
}
//设置用户缓存数据
function setCacheUser($user_id ,$value ,$uniacid = '7777')
{
$key = 'longbing_ws_card_user_' . $user_id;
return setCache ( $key, $value, 3600, $uniacid);
}
//获取用户信息
function getUser($user_id ,$uniacid ='7777')
{
//判断缓存是否存在
$user = $this->getCacheUser($user_id ,$uniacid);
if(!empty($user)) return $user;
// //生成查询类
// $user_model = new ImUser();
// //获取数据
// $user = $user_model->getUser(['id' => $user_id ,'uniacid' => $uniacid]);
$user = longbingGetUser($user_id ,$uniacid);
if(empty($user)) return null;
$this->setCacheUser($user_id ,$user ,$uniacid);
return $user;
}
//获取当前连接状态
function getConnect($client_id ,$uniacid = 'ws')
{
$key = $this->connect_name . $client_id;
$connect = getCache($key ,$uniacid);
return $connect;
}
//设置连接状态
function setConnect($client_id ,$value , $uniacid = 'ws')
{
$key = $this->connect_name . $client_id;
return setCache ( $key, $value, 3600, $uniacid);
}
//注销连接
function delConnect($client_id ,$uniacid = 'ws')
{
$key = $this->connect_name . $client_id;
$connect = $this->getConnect($client_id ,$uniacid);
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) return false;
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
if(isset($user['client_id'])){
unset($user['client_id']);
$this->setCacheUser($connect['user_id'],$user, $connect['uniacid']);
}
delCache($key ,$uniacid);
}
//获取所有chat
function getChats($user_id ,$uniacid = '7777' ,$is_update = false)
{
// $key = $this->chat_name . $user_id;
// $chats = [];
// //判断是否更新
// if($is_update)
// {
// $chat_model = new ImChat();
// $chats_data = $chat_model->listChatAll($user_id ,$uniacid);
// foreach($chats_data as $chat)
// {
// if(!isset($chat['chat_id']) || !isset($chat['user_id']) || !isset($chat['target_id'])) continue;
// $customer_id = $chat['user_id'];
// if(!in_array($chat['user_id'], [$user_id])) $customer_id = $chat['target_id'];
// $chats[$customer_id] = $chat['chat_id'];
// }
// if(!empty($chats)) $this->setChat($user_id ,$chats ,$uniacid);
// }else{
// if(hasCache($key ,$uniacid)){
// $chats = getCache($key ,$uniacid);
// }else{
// $chats = $this->getChats($user_id ,$uniacid ,true);
// }
// }
// return $chats;
$key = $this->chat_name . $user_id;
$chats = [];
if(hasCache($key ,$uniacid)){
$chats = getCache($key ,$uniacid);
}
return $chats;
}
//获取用户与客户的chat
function getChatId($user_id ,$customer_id ,$uniacid ,$is_create = false)
{
// //获取chats
// $chats = $this->getChats($user_id ,$uniacid);
// $chat_id = null;
// //判断数据是否存在
// if(!isset($chats[$customer_id])){
// $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
// $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
// }else{
// $chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
// }
// //返回数据
// return $chat_id;
//获取chats
$chats = $this->getChats($user_id ,$uniacid);
$chat_id = null;
//判断数据是否存在
if(!isset($chats[$customer_id])){
//从数据库中查询数据
$chat = $this->getChat($user_id, $customer_id ,$uniacid);
if(empty($chat))
{
if(!empty($is_create)){
$chat_id = $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
// $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
}
}else{
$chats[$customer_id] = $chat['chat_id'];
$this->setChat($user_id, $chats ,$uniacid);
}
}else{
$chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
}
//返回数据
return $chat_id;
}
//获取chat
function getChat($user_id ,$customer_id ,$uniacid = '7777')
{
$chat_model = new ImChat();
$chat = $chat_model->getChat($user_id ,$customer_id ,$uniacid);
return $chat;
}
//设置Chat
function setChat($user_id ,$value ,$uniacid ='7777')
{
$key = $this->chat_name . $user_id;
return setCache($key, $value, 60, $uniacid);
}
//创建Chat
function createChat($data)
{
$chat_model = new ImChat();
$result = $chat_model->createChat($data);
//$this->getChats($data['user_id'] ,$data['uniacid'] ,true);
return $result;
}
//获取客户列表
function listCustomer($data)
{
//获取参数列表
$param = $this->$data;
//获取用户列表
$user_id = $param['user_id'];
//判断用户是否存在
if(empty($user_id)) return $this->error('not login ,please login again.');
//生成分页信息
$page_config = array(
'page' => 1,
'page_count' => 10
);
//获取分页信息
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
//生成查询模型
$chat_model = new ImChat();
//生成消息查询模型
$message_model = new ImMessage();
//生成用户查询模型
// $user_model = new ImUser();
//生成查询
$page_config['total'] = $chat_model->listChatCount($user_id);
$chats = $chat_model->listChat($user_id ,$page_config);
if(!empty($chats))
{
foreach($chats as $key => $value)
{
$lastmessage = $message_model->lastMessage(['chat_id' => $value['id']]);
$value['lastmessage'] = $lastmessage;
$customer_id = null;
if(!in_array($value['user_id'], [$user_id])) $customer_id = $value['user_id'];
if(!in_array($value['target_id'], [$user_id])) $customer_id = $value['target_id'];
// $value['customer'] = $user_model->getUser(['id' => $customer_id]);
$value['customer'] = longbingGetUser($customer_id ,$value['uniacid']);
$chats[$key] = $value;
}
}
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
$result = $page_config;
$result['chats'] = $chats;
return $this->success($result);
}
//获取未读消息总数
public function getUnReadMessageCount($server ,$client_id ,$data)
{
//登录检查
if(!$this->checkLogin($client_id ,$data['data'])){
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
return;
}
//获取用户是否登录
$connect = $this->getConnect($client_id);
$user = null;
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
{
return;
}else{
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
}
//判断用户是否存在
if(empty($user)) return ;
//判断连接是否正确
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
{
$user['client_id'] = $client_id;
$this->setCacheUser($connect['user_id'], $user ,'ws');
}
//获取未读消息总数
$message_model = new ImMessage();
// $server->push($client_id ,json_encode($user));
$count = $message_model->listMessageCount(['target_id' => $user['id'] ,'status' => 1]);
// $count = $message_model->listMessageCount(['status' => 1]);
$server->push($client_id ,json_encode(['action' => 'getUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count]]));
return;
}
//获取用户未读消息数
public function getCustomerUnReadMessageCount($server ,$client_id ,$data)
{
//登录检查
if(!$this->checkLogin($client_id ,$data['data'])){
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
return;
}
if(!isset($data['data']['target_id'])) return;
$customer_id = $data['data']['target_id'];
//获取用户是否登录
$connect = $this->getConnect($client_id);
$user = null;
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
{
return;
}else{
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
}
//判断用户是否存在
if(empty($user)) return ;
//判断连接是否正确
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
{
$user['client_id'] = $client_id;
$this->setCacheUser($connect['user_id'], $user ,'ws');
}
//获取未读消息总数
$message_model = new ImMessage();
$chat_id = $this->getChatId($user['id'] ,$customer_id ,$user['uniacid'] ,true);
if(empty($chat_id)) return;
$count = $message_model->listMessageCount(['user_id' => $customer_id,'target_id' => $user['id'] ,'status' => 1]);
// $count = $message_model->listMessageCount(['status' => 1]);
$server->push($client_id ,json_encode(['action' => 'getCustomerUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count ,'target_id' => $customer_id ,'user_id' => $user['id']]]));
return;
}
//获取客户信息
public function getCustomer($server ,$client_id ,$data)
{
//登录检查
if(!$this->checkLogin($client_id ,$data['data'])){
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
return;
}
if(!isset($data['data'])) return;
if(!isset($data['data']['user_id'])) return;
if(!isset($data['data']['target_id'])) return;
if(!isset($data['data']['uniacid'])) return;
$user_id = $data['data']['user_id'];
$customer_id = $data['data']['target_id'];
$uniacid = $data['data']['uniacid'];
//生成关系操作类
$chat_model = new ImChat();
//获取chat_id
$chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid ,true);
if(empty($chat_id)) return;
//获取数据
$chat = $chat_model->getChatById($chat_id);
if(empty($chat)) return;
//获取客户信息
$customer = $this->getUser($customer_id ,$uniacid);
$chat['customer'] = $customer;
$chat['time'] = date('Y-m-d H:i:s', time());
if(isset($chat['update'])) $chat['time'] = date('Y-m-d H:i:s', $chat['update']);
$message_model = new ImMessage();
//获取最后一条消息
$last_message = $message_model->lastMessage(['chat_id' => $chat_id]);
$chat['lastmessage'] = $last_message;
//获取未读客户数据数量
$not_rear_message_count = $message_model->listMessageCount(['chat_id' => $chat_id ,'user_id' => $customer_id ,'target_id' =>$user_id ,'status' => 1]);
$chat['not_read_message_count'] = $not_rear_message_count;
//返回数据
$server->push($client_id ,json_encode(['action' => 'getCustomer' ,'status' => true ,'data' => $chat ,'message' => ''] ,true));
}
//检查链接是否正常
public function checkWs($server ,$client_id ,$data)
{
if(!isset($data['data']['check']) || !in_array($data['data']['check'], ['78346+SJDHFA.longbing'])) return ;
// $server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message'=> '' ,'data' =>['check' => '78346+SJDHFA.longbing']]));
$server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message' => '' ,'data' => ['check' => '78346+SJDHFA.longbing']]));
}
//标记消息已读
public function readMessage($server ,$client_id ,$data)
{
//登录检查
if(!$this->checkLogin($client_id ,$data['data'])){
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
return;
}
//获取用户是否登录
$connect = $this->getConnect($client_id);
$user = null;
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
{
return;
}else{
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
}
//判断用户是否存在
if(empty($user)) return ;
//判断连接是否正确
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
{
$user['client_id'] = $client_id;
$this->setCacheUser($connect['user_id'], $user ,'ws');
}
if(!isset($data['data']['target_id'])) return ;
$target_id = $data['data']['target_id'];
if(isset($data['data']['uniacid'])) $uniacid = $data['data']['uniacid'];
if(isset($user['uniacid'])) $uniacid = $user['uniacid'];
$user_id = $user['id'];
$chat_id = $this->getChatId($user_id, $target_id ,$uniacid , true);
if(empty($chat_id)) return;
//设置已读数据
$message_model = new ImMessage();
$message_model->readMessage(['chat_id' => $chat_id ,'user_id' => $target_id ,'target_id' => $user_id ,'deleted' => 0]);
//发数据给自己
$this->getCustomer($server ,$client_id ,['data' => ['user_id' => $user_id ,'target_id' => $target_id,'uniacid' => $uniacid]]);
//
$this->getUnReadMessageCount($server ,$client_id ,['data' => ['user_id' => $user_id,'target_id' => $target_id ,'uniacid' => $uniacid]]);
}
}

View File

@@ -0,0 +1,220 @@
<?php
namespace app\im\controller;
use app\Common\LongbingServiceNotice;
use app\Common\service\LongbingUserInfoService;
use app\im\service\ImService;
use longbingcore\tools\LongbingStr;
use longbingcore\tools\LongbingTime;
use think\App;
class MessageHandlerV2 extends BaseMessage
{
//连接客户端ID
protected $connect_name = 'longbing_im_connect_';
//链接对应的用户ID
protected $connect_user_name = 'longbing_im_connect_user';
//房间ID
protected $chat_name = 'longbing_chat_';
protected $uniacid_wss = 'wss';
protected $noLogin = ['code' => 401, 'error' => '请登录系统!'] ;
//发送消息
public function sendMessage($server ,$client_id ,$data)
{
//检查登录
$user_id = $this->checkLogin($server ,$client_id ,$data);
if(!$user_id){
return $this->sendLogin($server , $client_id ) ;
}
$uniacid = $data['data']['uniacid'];
$target_id = $data['data']['target_id']; //接收消息用户id
$content = $data['data']['content'];
if( isset($data['data']['id']) && $data['data']['id'] > 0 ) { //
$message = $data['data'] ;
$message_type = $data['data']['message_type'];
}else{
$chat_id = ImService::getChatId($uniacid, $user_id, $target_id);
$message_type = $data['data']['type'];
$message['message_type'] = $message_type; //
$message['status'] = 1; //消息状态 1=>未读消息 2=>已读 3=>已撤销 4=>已删除
$message['user_id'] = $user_id; //发送消息用户id
$message['target_id'] = $target_id; //接收消息用户id
$message['content'] = $content; // 消息内容
$message['uniacid'] = $uniacid; //平台ID
$message['chat_id'] = $chat_id; // 房间ID
$message['create_time'] = time();
$message['update_time'] = time();
ImService::addMessage($message);
}
$pushTargetClientId = intval( $this->getClientIdByUserId($target_id) ) ;
//客户在线
if($pushTargetClientId){
$this->sendServerMsg($server , $pushTargetClientId , 'getNewMessage' ,true,'', $message );
$this->getUnReadMessageCount($server , $pushTargetClientId , ['data'=>['user_id' => $target_id ] ] );
$this->getCustomerUnReadMessageCount($server , $pushTargetClientId , ['data'=>['user_id' => $target_id ,'target_id' => $user_id ] ] );
}else{
//发送服务通知给客户
//员工姓名,必须为中文,不能带有数字和符号
//$name = LongbingUserInfoService::getNameByUserId($user_id);
//ImService::sendTmplMsg($uniacid,$target_id,[ $name , '有未读私信' , LongbingTime::getChinaNowTime()] , 'pages/user/home' );
}
$this->sendServerMsg($server , $client_id , 'sendMessage' ,true,'', $message );
$this->getUnReadMessageCount($server , $client_id , ['data'=>['user_id' => $user_id ] ] );
//给员工发通知消息
//$note = new LongbingServiceNotice($uniacid);
//$note->sendImMessageServiceNoticeToStaff($target_id , $content) ;
}
//获取未读消息总数
public function getUnReadMessageCount($server ,$client_id ,$data)
{
$user_id = $data['data']['user_id'] ;
$count = ImService::getUnReadMessageCount($user_id);
$this->sendServerMsg($server ,$client_id , 'getUnReadMessageCount' , true,'', ['count' => $count ] ) ;
}
//查询目标客户,给我发送的消息数量
public function getCustomerUnReadMessageCount($server ,$client_id ,$data)
{
if (isset($data['data']['target_id']) && isset($data['data']['user_id'])) {
$user_id = $data['data']['user_id'];
$target_id = $data['data']['target_id'];
$count = ImService::getUnReadMessageCountByUserIdAndTargetId( $target_id , $user_id);
$this->sendServerMsg($server, $client_id, 'getCustomerUnReadMessageCount', true, '', ['count' => $count, 'user_id' => $user_id , 'target_id' => $target_id ]);
}
}
//登陆
public function login($server ,$client_id ,$data)
{
//登录失败
$user_id = $this->checkLogin($server ,$client_id ,$data);
if(!$user_id){
return $this->sendLogin($server , $client_id ) ;
}
$this->updateClentAndUserIdCache($client_id , $user_id);
$this->sendServerMsg($server ,$client_id , 'login' , true ) ;
//用户登录成功,给客户发未读消息数量
$this->getUnReadMessageCount($server , $client_id , ['data'=>['user_id' => $user_id ] ] );
}
//检查登录
public function checkLogin( $server ,$client_id ,$data ){
if(isset($data['data']['token'])){
$token = $data['data']['token'];
$uniacid = $data['data']['uniacid'] ;
$user = getCache($token , $uniacid );
if(empty($user)){
return false ;
}
return $user['id'] ;
}else{
echo json_encode($data);
}
return false ;
}
//发送登录提示消息信息
public function sendLogin( $server ,$client_id ){
$this->sendServerMsg($server, $client_id ,'login',false,'',$this->noLogin);
}
//更新缓存客户和用户ID
public function updateClentAndUserIdCache($client_id , $user_id){
//缓存客户端对应的用户ID
$key = $this->connect_name . $client_id;
setCache ( $key, $user_id, 3600, $this->uniacid_wss );
//缓存用户登录对应的客户端ID
$key = $this->connect_user_name . $user_id;
setCache ( $key, $client_id, 3600, $this->uniacid_wss );
}
//根据用户ID获取 $client_id
public function getClientIdByUserId($userId){
$key = $this->connect_user_name . $userId;
$client_id = getCache( $key , $this->uniacid_wss ) ;
return $client_id;
}
//退出
public function logout($client_id)
{
$key = $this->connect_name . $client_id;
$user_id = getCache( $key , $this->uniacid_wss ) ;
//删除客户对应的用户ID
delCache($key ,$this->uniacid_wss);
//删除用户对应的客户ID
$key = $this->connect_user_name . $user_id;
delCache($key ,$this->uniacid_wss);
}
//检查链接是否正常
public function checkWs($server ,$client_id ,$data)
{
//检查登录
$user_id = $this->checkLogin($server ,$client_id ,$data);
if(!$user_id){
return $this->sendLogin($server , $client_id ) ;
}
$this->updateClentAndUserIdCache($client_id , $user_id) ;
$this->sendServerMsg($server, $client_id ,'checkWsOk');
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace app\im\controller;
use app\im\controller\MessageHander;
//use think\swoole\Websocket as websocket;
use Swoole\Http\Server as HttpServer;
use Swoole\Websocket\Server as WebsocketServer;
use think\App;
use think\Route;
use think\swoole\command\Server as ServerCommand;
use think\swoole\facade\Server;
use think\swoole\websocket\socketio\Controller;
use think\swoole\websocket\socketio\Middleware;
use think\facade\Config;
//推送服务器
class PushServer extends \think\Service
{
private static $instance;
private static $server;
private $config;
//处理消息对象
private $messageHandler;
protected $isWebsocket = false;
public function __construct()
{
// parent::__construct();
//创建websocket对象
// self::$server = new swoole_websocket_server("0.0.0.0", 8006);
// self::$server = $server::$server;
// self::$server = new websocket("0.0.0.0", 8006);
$this->init();
$this->register();
//设置
// self::initServer();
//注册事件
//连接客户端
self::$server->on("open" ,[$this , "onOpen"]);
//发送消息
self::$server->on('message' ,[$this ,'onMessage']);
//关闭连接
self::$server->on('close' ,[$this ,'onClose']);
//异步
self::$server->on('task' ,[$this ,'onTask']);
//启动时运行
self::$server->on('workerStart' ,[$this ,'onWorkerStart']);
}
//获取
public static function getInstance()
{
if(!self::$instance instanceof self)
{
self::$instance = new self();
}
return self::$instance;
}
protected function init()
{
$this->config = Config::get('swoole');
}
public function register()
{
$this->isWebsocket = Config::get('swoole.websocket.enabled');
$this->createSwooleServer();
}
public function boot(Route $route)
{
$this->commands(ServerCommand::class);
if ($this->isWebsocket) {
$route->group(function () use ($route) {
$route->get('socket.io/', '@upgrade');
$route->post('socket.io/', '@reject');
})->prefix(Controller::class)->middleware(Middleware::class);
}
}
/**
* Create swoole server.
*/
protected function createSwooleServer()
{
$server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
$config = $this->config;
$host = Config::get('swoole.server.host');
$port = Config::get('swoole.server.port');
$socketType = Config::get('swoole.server.socket_type', SWOOLE_SOCK_TCP);
$mode = Config::get('swoole.server.mode', SWOOLE_PROCESS);
self::$server = new $server($host, $port, $mode, $socketType);
$options = Config::get('swoole.server.options');
self::$server->set($options);
}
//启动服务器
public function start()
{
self::$server->start();
}
//客户端连接上后执行的方法
public function onOpen($server ,$req)
{
self::$server->push($req->fd ,json_encode(['action' => 'connect' ,'status' => true ,'data' => [] ,'message' => 'connect success.'] ,true));
}
//客户端连接上后执行的方法
public function onMessage($server ,$frame)
{
self::$server->reload();//重新加载代码
$data = json_decode($frame->data ,true);
$result = null;
if(method_exists($this->messageHandler, $data['action']))
{
$result = call_user_func([$this->messageHandler, $data['action']] ,self::$server ,$frame->fd ,$data);
}
}
//异步
public function onTask($server ,$frame)
{
}
//关闭连接
public function onClose($server ,$fd)
{
call_user_func([$this->messageHandler, 'logout'] ,$fd);
}
//onWorkerStart
public function onWorkerStart()
{
// 加载框架里面的文件
require __DIR__ . '/../../../vendor/autoload.php';
$http = ( new App() )->http;
$response = $http->run();
$this->messageHandler = new MessageHandlerV2();
}
//发送消息
public function sendMessage($fd ,$data){
self::$server->push($fd ,$data);
}
}

612
app/im/controller/Some.php Normal file
View File

@@ -0,0 +1,612 @@
<?php
namespace app\im\controller;
use app\card\model\UserInfo;
use app\material\model\BrochureIm;
use app\material\model\ImVideo;
use app\shop\model\IndexUser;
use Redis;
use think\facade\Cache;
use think\facade\Config;
class Some {
public $redis;
public function __construct() {
$host = Config::get('cache.stores.redis.host');
$port = Config::get('cache.stores.redis.port');
$password = Config::get('cache.stores.redis.password');
if(empty($this->redis)||$this->redis->ping()!=true){
$this->redis = new Redis();
$this->redis->connect($host,$port);
if(!empty($password)){
$this->redis->auth($password); //设置密码
}
// $connect_status = $this->redis->ping();
// if($connect_status != "+PONG")
// if($connect_status != true)
// {
// $this->redis->connect($host,$port);
//
// if(!empty($password)){
//
// $this->redis->auth($password); //设置密码
// }
//
// }
}
}
/**
* @param $ws
* @param $request
* @功能说明:建立连接回调(智能物料)
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function mOnOpen($data,$fd) {
$room_key = $data['room_key'];
$uid = !empty($data['user_id'])?$data['user_id']:0;
$target_id= !empty($data['target_id'])?$data['target_id']:0;
$uniacid = !empty($data['uniacid'])?$data['uniacid']:0;
//是否是群主
$leader =!empty($data['presenter'])?$data['presenter']:0;
//1是文件 2是宣传册
$type = !empty($data['type'])?$data['type']:1;
//加入房间域
$this->redis->hset($room_key,$uid,$fd);
//加入组集合
$this->redis->sadd('group', $room_key);
//如果是群主
if($leader==1){
$key = $room_key.'-leader';
//群主
$this->redis->set($key,$uid,86400);
}
$bIm_model = new BrochureIm();
$dis = [
'user_id' => $uid,
'room_key' => $room_key,
'brochure_id' => $target_id,
'type' => $type,
];
$find = $bIm_model->dataInfo($dis);
$room_status = $bIm_model->where(['room_key'=>$room_key,'leader'=>1])->value('status');
$room_status = !empty($room_status)?$room_status:1;
if(empty($find)){
$key = $room_key.'-leader';
//群主
$user_id = $this->redis->get($key);
$user_info = new UserInfo();
$user_id = !empty($user_id)?$user_id:0;
$company_id = $user_info->where(['fans_id'=>$user_id])->value('company_id');
$insert = [
'uniacid' => $uniacid,
'user_id' => $uid,
'room_key' => $room_key,
'brochure_id' => $target_id,
'leader' => $leader,
'type' => $type,
'company_id' => !empty($company_id)?$company_id:0,
'status' => $room_status
];
$bIm_model->dataAdd($insert);
}else{
$bIm_model->dataUpdate($dis,['status'=>$room_status]);
}
}
/**
* @param $ws
* @param $frame
* @功能说明:接受消息回调(智能物料)
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function mOnMessage($ws, $data,$fd) {
$room_key = $data['data']['room_key'];
//获取房间
$room = $this->redis->hGetAll($room_key);
if(!empty($room)){
foreach ($room as $k => $vv) {
//投递消息
$ws->push($vv, json_encode($data));
}
}
}
/**
* @param $ws
* @param $data
* @param $fd
* @功能说明:保存音频
* @author chenniang
* @DataTime: 2021-08-10 17:25
*/
public function addVideo($ws, $data,$fd){
$room_key = $data['data']['room_key'];
$uniacid = !empty($data['data']['uniacid'])?$data['data']['uniacid']:0;
$video = FILE_UPLOAD_PATH.$data['data']['video'];
if(!empty($data['data']['video'])){
$im_video_model = new ImVideo();
$insert = [
'uniacid' => $uniacid,
'room_key' => $room_key,
'video' => $video,
];
$im_video_model->dataAdd($insert);
}
}
/**
* @param $ws
* @param $frame
* @功能说明:接受消息回调(智能物料)
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function onLogin($ws, $data,$fd) {
$room_key = $data['data']['room_key'];
// $room_key = '20210802093606035000000350';
//获取房间
$room = $this->redis->hgetall($room_key);
if(!empty($room)){
$user_model = new IndexUser();
$bIm_model = new BrochureIm();
$user_id = array_keys($room);
$key = $room_key.'-leader';
//获取群组的用户id
$leader_id = $this->redis->get($key);
if(!empty($leader_id)){
$user_key = array_search($leader_id,$user_id);
if(is_numeric($user_key)&&array_key_exists($user_key,$user_id)){
unset($user_id[$user_key]);
}
}
$user = $user_model->where('id','in',$user_id)->field('nickName,avatarUrl')->select()->toArray();
$list['data']['user'] = $user;
$list['action'] = $data['action'];
$list['data']['room_key'] = $room_key;
$list['data']['count'] = count($user_id);
$dis = [
'room_key' => $room_key,
'leader' => 1
];
//演示状态
$list['data']['is_start'] = $bIm_model->where($dis)->value('status');
foreach ($room as $k => $vv) {
//投递消息
$ws->push($vv, json_encode($list));
}
}
}
/**
* @author chenniang
* @DataTime: 2021-07-28 16:50
* @功能说明:开始演示
*/
public function startAction($ws, $data,$fd){
$room_key = $data['data']['room_key'];
$bIm_model = new BrochureIm();
$dis = [
'room_key' => $room_key,
// 'leader' => 1
];
//修改演示状态
$bIm_model->dataUpdate($dis,['status'=>2]);
$bIm_model->dataUpdate(['room_key'=>$room_key],['time_long'=>0,'update_time'=>time()]);
$room = $this->redis->hGetAll($room_key);
$list['data']['is_start'] = 2;
$list['data']['room_key'] = $room_key;
$list['action'] = $data['action'];
if(!empty($room)){
foreach ($room as $k=>$vv){
//投递消息
$ws->push($vv, json_encode($list));
}
}
}
/**
* @param $serv
* @param $task_id
* @param $worker_id
* @param $data
* @功能说明:完成异步任务回调
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function onTask($serv, $task_id, $worker_id, $data) {
//返回字符串给worker进程——>触发onFinish
return "success";
}
/**
* @param $serv
* @param $task_id
* @param $data
* @功能说明:完成任务投递回调
* @author chenniang
* @DataTime: 2021-07-02 18:16
*/
public function onFinish($serv, $task_id, $data) {
//task_worker进程将任务处理结果发送给worker进程
echo "完成任务{$task_id}投递 处理结果:{$data}";
}
/**
* @param $ws
* @param $fd
* @功能说明:关闭连接回调
* @author chenniang
* @DataTime: 2021-07-02 18:16
*/
public function onClose($ws, $fd) {
//退出并删除多余的分组fd
$group = $this->redis->sMembers('group');
foreach ($group as $v) {
$fangjian = $this->redis->hgetall($v);
foreach ($fangjian as $k => $vv) {
if ($fd == $vv) {
$this->redis->hdel($v, $vv);
}
}
}
// echo "{$fd}关闭了连接1";
}
/**
* @param $ws
* @param $fd
* @功能说明:解散群
* @author chenniang
* @DataTime: 2021-07-27 18:04
*/
public function allLoginOut($ws,$data,$fd){
$room_key = $data['data']['room_key'];
$fangjian = $this->redis->hgetall($room_key);
$im_model = new BrochureIm();
$data['action'] = 'mOnMessage';
$data['data']['message_type'] = 2;
//给剩下的人发消息
$this->mOnMessage($ws,$data,$fd);
$bIm_model = new BrochureIm();
$dis = [
'room_key' => $room_key,
];
//修改演示状态
$bIm_model->where($dis)->update(['status'=>3]);
if(!empty($fangjian)){
foreach ($fangjian as $k => $vv) {
$this->redis->Hdel($room_key,$k);
$dis = [
'user_id' => $k,
'room_key'=> $room_key
];
$find = $im_model->dataInfo($dis);
if(!empty($find)&&$find['status']>1){
$time_long = time()-$find['update_time'];
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
}
}
//删除房间
@$this->redis->sRem('group',$room_key);
}
// if(!empty($data['data']['url'])){
//
// $url = $data['data']['url'];
// //合并录音
// $im_model->addAudio($room_key,$url);
// }
}
/**
* @param $ws
* @param $fd
* @功能说明:退出
* @author chenniang
* @DataTime: 2021-07-23 17:44
*/
public function loginOut($ws, $fd){
$im_model = new BrochureIm();
//退出并删除多余的分组fd
$group = $this->redis->sMembers('group');
if(!empty($group)){
foreach ($group as $v) {
$fangjian = $this->redis->hgetall($v);
$data['data']['room_key'] = $v;
if(!empty($fangjian)){
foreach ($fangjian as $k => $vv) {
if ($fd == $vv) {
$this->redis->Hdel($v,$k);
$dis = [
'user_id' => $k,
'room_key'=> $v
];
$find = $im_model->dataInfo($dis);
if(!empty($find)&&$find['status']>1){
$time_long = time()-$find['update_time'];
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
}
$data['action'] = 'onLogin';
//给剩下的人发消息
$this->onLogin($ws,$data,$fd);
}
}
}else{
@$this->redis->sRem('group',$v);
}
}
}
}
/**
* @param $ws
* @param $fd
* @功能说明:退出
* @author chenniang
* @DataTime: 2021-07-23 17:44
*/
public function loginOutV2($ws, $fd){
$im_model = new BrochureIm();
//退出并删除多余的分组fd
$group = $this->redis->sMembers('group');
foreach ($group as $v) {
$fangjian = $this->redis->hgetall($v);
$key = $v.'-leader';
//获取群组的用户id
$leader_id = $this->redis->get($key);
//当前用户的id
$user_id = array_search($fd,$fangjian);
//如果是群组则全部退出
$is_all = !empty($user_id)&&$leader_id==$user_id?1:0;
$data['data']['room_key'] = $v;
//修改房间状态
if($is_all==1){
$start_key = $v.'-is_start';
$this->redis->set($start_key,0);
$data['action'] = 'mOnMessage';
$data['data']['message_type'] = 2;
//给剩下的人发消息
$this->mOnMessage($ws,$data,$fd);
}
if(!empty($fangjian)){
foreach ($fangjian as $k => $vv) {
if ($fd == $vv||$is_all==1) {
$this->redis->hdel($v, $k);
$dis = [
'user_id' => $k,
'room_key'=> $v
];
$find = $im_model->dataInfo($dis);
if(!empty($find)){
$time_long = time()-$find['update_time'];
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
}
}
}
}else{
@$this->redis->sRem('group',$v);
}
//如果是群主断开链接
if($is_all==0){
$data['action'] = 'onLogin';
//给剩下的人发消息
$this->onLogin($ws,$data,$fd);
}
}
}
}

82
app/im/controller/Tcp.php Normal file
View File

@@ -0,0 +1,82 @@
<?php
// +----------------------------------------------------------------------
// | Longbing [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright Chengdu longbing Technology Co., Ltd.
// +----------------------------------------------------------------------
// | Website http://longbing.org/
// +----------------------------------------------------------------------
// | Sales manager: +86-13558882532 / +86-13330887474
// | Technical support: +86-15680635005
// | After-sale service: +86-17361005938
// +----------------------------------------------------------------------
use Swoole\WebSocket\Server;
use think\facade\Cache;
class Tcp {
public $server;
public $redis;
public $key;
public function __construct() {
if(empty($this->redis)){
$this->redis = new Redis();
$this->redis ->connect('127.0.0.1',6379);
}
//创建Server对象监听 127.0.0.1:9501 端口
$server = new \Swoole\Server('127.0.0.1', 9501);
// $this->server->set(array(
//
// 'reactor_num' => 2, //reactor thread num
//
// 'worker_num' => 4, //worker process num
//
// 'backlog' => 128, //listen backlog
//
// 'max_request' => 50,
//
// 'dispatch_mode' => 1,
//
//// 'daemonize' => 1
//
// ));
//监听连接进入事件
$server->on('Connect', function ($server, $fd) {
echo "Client: Connect.\n";
});
//监听数据接收事件
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
$server->send($fd, "Server: {$data}");
});
//监听连接关闭事件
$server->on('Close', function ($server, $fd) {
echo "Client: Close.\n";
});
//启动服务器
$server->start();
}
}
new Tcp();

View File

@@ -0,0 +1,142 @@
<?php
// +----------------------------------------------------------------------
// | Longbing [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright Chengdu longbing Technology Co., Ltd.
// +----------------------------------------------------------------------
// | Website http://longbing.org/
// +----------------------------------------------------------------------
// | Sales manager: +86-13558882532 / +86-13330887474
// | Technical support: +86-15680635005
// | After-sale service: +86-17361005938
// +----------------------------------------------------------------------
use Swoole\WebSocket\Server;
use think\facade\Cache;
class WebsocketTest {
public $server;
public $redis;
public $key;
public function __construct() {
$this->key = '122345446';
if(empty($this->redis)){
$this->redis = new Redis();
$this->redis ->connect('127.0.0.1',6379);
}
$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$this->server->set(array(
'reactor_num' => 2, //reactor thread num
'worker_num' => 4, //worker process num
'backlog' => 128, //listen backlog
'max_request' => 50,
'dispatch_mode' => 1,
// 'daemonize' => 1
));
$this->server->on('open', function (swoole_websocket_server $server, $request) {
//加入房间域
$this->redis->hset($this->key,$request->fd,$request->fd);
//加入组集合
$this->redis->sadd('group', $this->key);
});
$this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
// echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$group = $this->redis->sMembers('group');
foreach ($group as $v) {
$fangjian = $this->redis->hGetAll($v);
foreach ($fangjian as $k => $vv) {
$server->push($vv, count($fangjian).$frame->fd);
}
}
});
$this->server->on('close', function ($server, $fd) {
$this->redis->hdel($this->key, 2);
//echo "client {$fd} closed\n";
//退出并删除多余的分组fd
$group = $this->redis->sMembers('group');
foreach ($group as $v) {
$fangjian = $this->redis->hgetall($v);
foreach ($fangjian as $k => $vv) {
// if ($fd == $vv) {
$this->redis->hdel($v, $vv);
// }
}
}
});
//
$this->server->on('request', function ($request, $response) {
// 接收http请求从get获取message参数的值给用户推送
// $this->server->connections 遍历所有websocket连接用户的fd给所有用户推送
foreach ($this->server->connections as $fd) {
// 需要先判断是否是正确的websocket连接否则有可能会push失败
if ($this->server->isEstablished($fd)) {
$this->server->push($fd, '11');
}
}
});
$this->server->start();
}
}
new WebsocketTest();

197
app/im/controller/Ws.php Normal file
View File

@@ -0,0 +1,197 @@
<?php
namespace app\im\controller;
use app\im\controller\MessageHandlerV2;
use app\material\model\BrochureIm;
use Exception;
use Swoole\WebSocket\Server;
use think\App;
use think\facade\Config;
use think\session\driver\Cache;
class Ws {
public $ws = null;
public $server;
public $redis;
public $key;
public $messageHandler;
public function __construct() {
// $this->key = '1223454461';
// 加载框架里面的文件
require __DIR__ . '/../../../vendor/autoload.php';
$http = ( new App() )->http;
$response = $http->run();
$this->ws = new Server("0.0.0.0", Config::get('swoole.server.mport'));
$this->ws->set([
//worker进程数
'worker_num' => 4,
//task进程数
'task_worker_num' => 4,
//listen backlog
'backlog' => 128,
'max_request' => 50,
//心跳检测 每隔多少秒,遍历一遍所有的连接
'heartbeat_check_interval' => 30,
//心跳检测 最大闲置时间超时触发close并关闭
'heartbeat_idle_time' => 65,
// 总开关用来开启tcp_keepalive
'open_tcp_keepalive' => 1,
// 4s没有数据传输就进行检测
'tcp_keepidle' => 10,
// 4s没有数据传输就进行检测
'tcp_keepcount' => 10,
// 1s探测一次即每隔1s给客户端发一个包然后客户端可能会回一个ack的包如果服务端收到了这个ack包那么说明这个连接是活着的'tcp_keepcount' => 5,
// 探测的次数超过5次后客户端还没有回ack包那么close此连接
'tcp_keepinterval' => 5,
'log_file' => '/www/wwwroot/swoole.log',
'daemonize' => 1
]);
$this->ws->on("open", [$this, 'onOpen']);
$this->ws->on("message", [$this, 'onMessage']);
$this->ws->on("task", [$this, 'onTask']);
$this->ws->on("finish", [$this, 'onFinish']);
$this->ws->on("close", [$this, 'onClose']);
$this->ws->on('workerStart' ,[$this ,'onWorkerStart']);
$this->ws->start();
}
public function onWorkerStart()
{
$this->messageHandler = new Some();
}
/**
* @param $ws
* @param $request
* @功能说明:建立连接回调
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function onOpen($ws, $request) {
$request->get['action'] = !empty($request->get['action'])?$request->get['action']:'mOnOpen';
if(method_exists($this->messageHandler, $request->get['action']))
{
// try{
call_user_func([$this->messageHandler, $request->get['action']] , $request->get,$request->fd);
// }catch(Exception $e) {
//
// }
}
// echo FILE_UPLOAD_PATH;
}
/**
* @param $ws
* @param $frame
* @功能说明:接受消息回调
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function onMessage($ws, $frame) {
$data = @json_decode($frame->data,true);
if(is_array($data)){
if(method_exists($this->messageHandler, $data['action']))
{
// try{
call_user_func([$this->messageHandler, $data['action']] ,$ws,$data,$frame->fd);
// }catch(Exception $e) {
//
// }
}
}
}
/**
* @param $serv
* @param $task_id
* @param $worker_id
* @param $data
* @功能说明:完成异步任务回调
* @author chenniang
* @DataTime: 2021-07-02 18:17
*/
public function onTask($serv, $task_id, $worker_id, $data) {
//返回字符串给worker进程——>触发onFinish
return "success";
}
/**
* @param $serv
* @param $task_id
* @param $data
* @功能说明:完成任务投递回调
* @author chenniang
* @DataTime: 2021-07-02 18:16
*/
public function onFinish($serv, $task_id, $data) {
//task_worker进程将任务处理结果发送给worker进程
echo "完成任务{$task_id}投递 处理结果:{$data}";
}
/**
* @param $ws
* @param $fd
* @功能说明:关闭连接回调
* @author chenniang
* @DataTime: 2021-07-02 18:16
*/
public function onClose($ws, $fd) {
// try{
call_user_func([$this->messageHandler, 'loginOut'] ,$ws, $fd);
// }catch(Exception $e) {
//
// }
// echo "{$fd}关闭了连接1";
}
}
$obj = new Ws();

82
app/im/controller/net.php Normal file
View File

@@ -0,0 +1,82 @@
<?php
//SOCKET
//
class net
{
public $socket = 0;
//func
function listen($ip, $port)
{
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($this->socket, $ip, $port);
$ex = socket_listen($this->socket, 4);
//socket_bind($this->socket, '127.0.0.1', $port) or die("socket_bind() fail:" . socket_strerror(socket_last_error()) . "/n");
//$ex = socket_listen($this->socket, 4) or die("socket_listen() fail:" . socket_strerror(socket_last_error()) . "/n");
return $ex;
}
function accept()
{
return socket_accept($this->socket);
}
function close()
{
if($this->socket == 0) return;
socket_close($this->socket);
$this->socket = 0;
}
function send_bytes($cs, $bytes)
{
$str = $this->bytes_to_string($arr);
$ex = $this->send($cs, $str);
return $ex;
}
function recv_bytes($cs, $len = 1024)
{
$ret = $this->recv($cs, $len);
$bytes = $this->string_to_bytes($ret);
return $bytes;
}
function send($cs, $msg)
{
$ex = socket_write($cs, $msg);
return $ex;
}
function recv($cs, $len = 1024)
{
$ret = socket_read($cs, $len);
return $ret;
}
///accessibility
function bytes_to_string($bytes)
{
$str = '';
for($i=0; $i<count($bytes); $i++)
{
$str .= chr($bytes[$i]);
}
return $str;
}
function string_to_bytes($str)
{
$bytes = array();
for($i=0; $i<strlen($str); $i++)
{
$bytes[] = ord($str[$i]);
}
return $bytes;
}
}
?>

View File

@@ -0,0 +1,61 @@
<?php
//include 'crc.php';
include 'net.php';
//打印十六进制(可以不用)
function println($bytes) {
for($i=0;$i<count($bytes);$i++)
{
printf("%02X ", $bytes[$i]);
}
printf(".");
}
//这里开始
$net = new net();
$net->listen('192.168.1.55', 50000);
while(true) {
$cs = $net->accept();
while($cs) {
try{
$ret = $net->recv_bytes($cs, 1024);
abc($ret);
//println($ret);
}
catch (Exception $e)
{
//printf('cs close');
break;
}
}
}
$net->close();
//abc处理读取到的卡4字节
function abc($ret)
{
$len = $ret[4];
if($len < 14)
{
//printf('无效数据');
return ;
}
//
$count = $ret[9];
$count = ($count - 3) / 4;
//
for($i=0; $i<$count; $i++)
{
$idx = 10 + ($i * 4);
$card = sprintf("%02X%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2], $ret[$idx+3]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了
printf('card['.$i.']>>'.$card.' | ');
}
}
?>