You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
14 KiB
292 lines
14 KiB
<?php
|
|
define('IN_UNIAPP',true);
|
|
error_reporting(0);
|
|
header('Access-Control-Allow-Origin:*');
|
|
require '../../../../framework/bootstrap.inc.php';
|
|
require '../../../../addons/'.MODULE_NAME.'/core/common/defines.php';
|
|
require PATH_MODULE."/vendor/autoload.php";
|
|
require PATH_CORE."common/autoload.php";
|
|
Func_loader::core('global');
|
|
global $_W,$_GPC,$db,$socket;
|
|
load()->model('attachment');
|
|
//获取基本设置信息
|
|
$set = pdo_get(PDO_NAME.'setting',['key' => 'im_set'],['value']);
|
|
if (is_array($set)) $set = iunserializer($set['value']);
|
|
$port = $set['port'];
|
|
$cert = $set['pem_path'];
|
|
$key = $set['key_path'];
|
|
//$cert = 'D:/Software/phpstudy_pro/Extensions/Nginx1.15.11/conf/ssl/www.locatiom.smartcity.com.pem';
|
|
//$key = 'D:/Software/phpstudy_pro/Extensions/Nginx1.15.11/conf/ssl/www.locatiom.smartcity.com.key';
|
|
|
|
//开始进行通讯处理
|
|
use Workerman\Worker;
|
|
require_once PATH_VENDOR.'workerman/workerman/Autoloader.php';
|
|
//创建一个Worker监听端口,使用websocket协议通讯
|
|
$context = [
|
|
// 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
|
|
'ssl' => [
|
|
'local_cert' => $cert,
|
|
'local_pk' => $key,
|
|
'verify_peer' => false,
|
|
// 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
|
|
]
|
|
];
|
|
$socket = new Worker("websocket://0.0.0.0:{$port}",$context);
|
|
$socket->transport = 'ssl';
|
|
//$socket->count = 4;//启动x个进程对外提供服务
|
|
$socket->onWorkerStart = function($worker) {
|
|
// 将db实例存储在全局变量中(也可以存储在某类的静态成员中)
|
|
global $db;
|
|
require '../../../../data/config.php';
|
|
$master = $config['db']['master'];
|
|
$db = new \Workerman\MySQL\Connection($master['host'],$master['port'], $master['username'], $master['password'],$master['database']);
|
|
};
|
|
//接收数据并且进行对应的处理
|
|
$socket->onMessage = function ($connection,$data) {
|
|
//处理信息
|
|
(new handle($data,$connection))->handleData();
|
|
};
|
|
//当某个链接断开时触发
|
|
$socket->onClose = function ($connection) {
|
|
|
|
|
|
};
|
|
//方法类
|
|
class handle{
|
|
private $data,//当前接收的消息
|
|
$sendId,//发送方唯一id
|
|
$receiveId,//接收方唯一id
|
|
$idsFile = PATH_CORE."common/im_ids.php";
|
|
|
|
public function __construct($data,$connection){
|
|
global $_W;
|
|
//data信息处理
|
|
$data = json_decode($data,true);
|
|
$_W['uniacid'] = $data['i'] ? : $data['uniacid'];//公众号id
|
|
$_W['aid'] = $data['aid'];//代理商id
|
|
$_W['source'] = $data['source'];//渠道
|
|
//通讯信息获取
|
|
$data['send_id'] = intval($data['send_id']) ? : $_W['mid'];//当前发送信息的用户的id(商户id)
|
|
$data['receive_id'] = intval($data['receive_id']);//接受消息的用户id(商户id)
|
|
$data['page'] = intval($data['page']) ? : 1;//页码
|
|
$data['page_index'] = intval($data['page_index']) ? : 10;//每页的数量
|
|
$this->sendId = $data['send_id'].'_'.$data['receive_id'];
|
|
$this->receiveId = $data['receive_id'].'_'.$data['send_id'];
|
|
$this->data = $data;
|
|
//通讯节点处理
|
|
$this->setIds($this->sendId,$connection->id);
|
|
}
|
|
/**
|
|
* Comment: 处理接收的data信息
|
|
* Author: zzw
|
|
* Date: 2021/3/8 11:44
|
|
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
|
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
|
*/
|
|
public function handleData(){
|
|
global $_W,$db;
|
|
//接受信息
|
|
$data = $this->data;
|
|
//判断是否给自己发送消息
|
|
if($data['send_id'] == $data['receive_id'] && $data['send_type'] == $data['receive_type']) $this->socketSend($this->sendId,"不能给自己发送信息哦",5);
|
|
//判断通讯类型,进行对应的操作。信息类型:1=系统信息,2=通信信息,3=断开链接,4=通讯记录,5=错误抛出
|
|
if($data['im_type'] == 2){
|
|
//记录信息到表
|
|
$newData['uniacid'] = $_W['uniacid'];
|
|
$newData['send_id'] = $data['send_id'];//发送方id
|
|
$newData['send_type'] = $data['send_type'];//发送方类型(1=用户;2=商户)
|
|
$newData['receive_id'] = $data['receive_id'];//接收人id
|
|
$newData['receive_type'] = $data['receive_type'];//接收人类型(1=用户;2=商户)
|
|
$newData['create_time'] = time();//发送时间(建立时间)
|
|
$newData['type'] = $data['type'];//内容类型:0=文本内容(可带表情),1=图片信息(不可带表情),2=视频信息(不可带表情),3=名片信息(不可带表情),4=简历信息(不可带表情),5=其他信息(不可带表情)
|
|
$newData['content'] = base64_encode($data['content']);//发送内容
|
|
$newData['plugin'] = $data['plugin'];//发送内容
|
|
$table = trim(tablename(PDO_NAME."im"),'`');
|
|
$db->insert($table)->cols($newData)->query();
|
|
//判断接收方是否在线 在线进行推送
|
|
$memberInfo = $db->select('nickname,avatar')
|
|
->from(trim(tablename(PDO_NAME."member"),'`'))
|
|
->where("id={$newData['send_id']}")
|
|
->row();
|
|
$sendInfo = [
|
|
'avatar' => tomedia($memberInfo['avatar']),
|
|
'content' => $data['content'],
|
|
'create_time' => $newData['create_time'],
|
|
'date_time' => date('Y-m-d H:i:s',$newData['create_time']),
|
|
'is_my' => 1,//0=自己发送的消息,1=对方发送的消息
|
|
'nickname' => $memberInfo['nickname'],
|
|
'receive_id' => $newData['receive_id'],
|
|
'send_id' => $newData['send_id'],
|
|
'type' => $newData['type']
|
|
];
|
|
|
|
$this->socketSend($this->receiveId,'即时通讯信息',2,$data['type'],['list'=>[$sendInfo]]);
|
|
}else if ($data['im_type'] == 3){
|
|
//断开链接
|
|
//$this->log(['断开',$data]);
|
|
$this->deleteIds($this->sendId);
|
|
}else if($data['im_type'] == 4){
|
|
//获取通讯记录信息
|
|
$sendInfo['send_id'] = $data['send_id'] ;//发送方id
|
|
$sendInfo['send_type'] = $data['send_type'] ;//发送方类型(1=用户;2=商户)
|
|
$sendInfo['receive_id'] = $data['receive_id'] ;//接收人id
|
|
$sendInfo['receive_type'] = $data['receive_type'] ;//接收人类型(1=用户;2=商户)
|
|
//$list = Im::imRecord($data['page'],$data['page_index'],$sendInfo);
|
|
$pageStart = $data['page'] * $data['page_index'] - $data['page_index'];
|
|
//条件生成
|
|
$where = " as a WHERE a.uniacid = {$_W['uniacid']} AND
|
|
(
|
|
(a.send_id = {$sendInfo['send_id']} AND a.send_type = {$sendInfo['send_type']} AND a.receive_id = {$sendInfo['receive_id']} AND a.receive_type = {$sendInfo['receive_type']})
|
|
OR
|
|
(a.send_id = {$sendInfo['receive_id']} AND a.send_type = {$sendInfo['receive_type']} AND a.receive_id = {$sendInfo['send_id']} AND a.receive_type = {$sendInfo['send_type']})
|
|
)";
|
|
if($data['plugin']) $where .= " AND a.plugin = {$data['plugin']} ";
|
|
else $where .= " AND (a.plugin = '' OR a.plugin IS NULL)";
|
|
//要查询的字段生成
|
|
$field = " a.id,a.send_id,a.`receive_id`,a.content,a.create_time,a.type,FROM_UNIXTIME(create_time,'%Y-%m-%d %H:%i:%S') as date_time,
|
|
CASE {$sendInfo['receive_id']} WHEN a.send_id THEN 1
|
|
ELSE 0
|
|
END as is_my,
|
|
CASE a.`send_type`
|
|
WHEN 1 THEN (SELECT `nickname` FROM ".tablename(PDO_NAME."member")." WHERE `id` = a.`send_id`)
|
|
ELSE (SELECT storename FROM ".tablename(PDO_NAME."merchantdata")." WHERE `id` = a.`send_id` )
|
|
END as nickname,
|
|
CASE a.`send_type`
|
|
WHEN 1 THEN (SELECT `avatar` FROM ".tablename(PDO_NAME."member")." WHERE `id` = a.`send_id`)
|
|
ELSE (SELECT logo FROM ".tablename(PDO_NAME."merchantdata")." WHERE `id` = a.`send_id` )
|
|
END as avatar";
|
|
#4、获取总页数
|
|
$totalSql = "SELECT COUNT(*) as total FROM ".tablename(PDO_NAME."im").$where;
|
|
$total = $db->single($totalSql);
|
|
$list['total'] = ceil($total / $data['page_index']);
|
|
#5、获取当前页列表信息
|
|
$listSql = "SELECT {$field} FROM ".tablename(PDO_NAME."im").$where
|
|
." ORDER BY a.create_time DESC LIMIT {$pageStart},{$data['page_index']} ";
|
|
$list['list'] = $db->query($listSql);
|
|
foreach($list['list'] as $key => &$val) {
|
|
$val['avatar'] = tomedia($val['avatar']);
|
|
if(is_base64($val['content'])) $val['content'] = base64_decode($val['content'],true);
|
|
}
|
|
//修改信息为已读
|
|
/*if(is_array($list['list']) && count($list['list']) > 0) {
|
|
//条件生成
|
|
$ids = array_column($list['list'],'id');
|
|
if(!empty($sendInfo['send_id'])) $where = " receive_id = {$sendInfo['send_id']} ";
|
|
else $where = " receive_id = {$_W['mid']} ";
|
|
if(count($ids) > 1){
|
|
$idStr = implode(',',$ids);
|
|
$where .= " AND id IN ({$idStr}) ";
|
|
}else{
|
|
$where .= " AND id = {$ids[0]} ";
|
|
}
|
|
#2、修改内容
|
|
$updateSql = "UPDATE ".tablename(PDO_NAME."im")." SET is_read = 1 WHERE ".$where;
|
|
$db->query($updateSql);
|
|
}*/
|
|
$where = " send_id = {$sendInfo['receive_id']} AND send_type = {$sendInfo['receive_type']} AND receive_id = {$sendInfo['send_id']} AND receive_type = {$sendInfo['send_type']} AND is_read = 0 ";
|
|
$sql = " UPDATE ".tablename(PDO_NAME."im")." SET is_read = 1 WHERE {$where} ";
|
|
$db->query($sql);
|
|
//信息排序
|
|
$sortArr = array_column($list['list'], 'create_time');
|
|
array_multisort($sortArr, SORT_ASC, $list['list']);
|
|
//获取聊天对象的昵称 1=用户;2=商户
|
|
if($sendInfo['receive_type'] == 1) {
|
|
$nicknameSql = "SELECT nickname FROM ".tablename(PDO_NAME."member")." WHERE id = {$sendInfo['receive_id']} ";
|
|
$list['receive_name'] = $db->single($nicknameSql);
|
|
} else {
|
|
$nicknameSql = "SELECT storename FROM ".tablename(PDO_NAME."merchantdata")." WHERE id = {$sendInfo['receive_id']} ";
|
|
$list['receive_name'] = $db->single($nicknameSql);
|
|
}
|
|
$this->socketSend($this->sendId,'通讯记录',4,5,$list);
|
|
}
|
|
}
|
|
/**
|
|
* Comment: 发送数据给移动端
|
|
* Author: zzw
|
|
* Date: 2021/3/8 11:44
|
|
* @param $id
|
|
* @param $content
|
|
* @param int $imType
|
|
* @param int $type
|
|
* @param array $other
|
|
*/
|
|
public function socketSend($id,$content,$imType = 2,$type = 0,$other = []){
|
|
global $socket;
|
|
//生成需要发送的信息
|
|
$data = [
|
|
'im_type' => $imType,//信息类型:1=系统信息,2=通信信息,3=断开链接,4=通讯记录,5=错误抛出
|
|
//具体通讯信息
|
|
'type' => $type,//内容类型:0=文本内容(可带表情),1=图片信息(不可带表情),2=视频信息(不可带表情),3=名片信息(不可带表情),4=简历信息(不可带表情),5=其他信息(数组)
|
|
'content' => $content,//文本内容
|
|
'other' => $other,//其他信息(名片信息|简历信息)
|
|
];
|
|
//发送信息
|
|
$connectionId = $this->getIds($id);
|
|
if($connectionId > 0){
|
|
$connection = $socket->connections[$connectionId];
|
|
|
|
if(is_object($connection)) $connection->send(json_encode($data,JSON_UNESCAPED_UNICODE));
|
|
}
|
|
}
|
|
/**
|
|
* Comment: 日志记录
|
|
* Author: zzw
|
|
* Date: 2021/3/8 11:44
|
|
* @param $content
|
|
* @param string $title
|
|
*/
|
|
public function log($content,$title = '日志'){
|
|
Util::wl_log('socket',PATH_MODULE . "log/",$content,$title,false);
|
|
}
|
|
/**
|
|
* Comment: 获取ids数组信息
|
|
* Author: zzw
|
|
* Date: 2021/3/12 10:21
|
|
* @param int $key 发送者id
|
|
* @return array|bool|Memcache|mixed|Redis|string
|
|
*/
|
|
public function getIds($id = 0){
|
|
//获取文件读写权限
|
|
if(!is_readable($this->idsFile)) chmod($this->idsFile,0755);
|
|
//获取文件内容
|
|
$data = file_get_contents($this->idsFile);
|
|
$data = json_decode($data,true);
|
|
if($id > 0) return $data[$id];
|
|
else return $data;
|
|
}
|
|
/**
|
|
* Comment: 设置id缓存
|
|
* Author: zzw
|
|
* Date: 2021/3/12 10:21
|
|
* @param int $key 发送者id
|
|
* @param int $val 通讯节点id
|
|
*/
|
|
public function setIds($key,$val){
|
|
header('Content-Type:text/html;charset=utf-8');
|
|
//数组转字符串
|
|
$data = $this->getIds();
|
|
$data[$key] = $val;
|
|
$idStr = json_encode($data,JSON_UNESCAPED_UNICODE);
|
|
file_put_contents($this->idsFile, print_r($idStr, true));
|
|
}
|
|
/**
|
|
* Comment: 删除id缓存
|
|
* Author: zzw
|
|
* Date: 2021/3/18 11:13
|
|
* @param $id
|
|
*/
|
|
public function deleteIds($id){
|
|
header('Content-Type:text/html;charset=utf-8');
|
|
//数组转字符串
|
|
$data = $this->getIds();
|
|
unset($data[$id]);
|
|
$idStr = json_encode($data,JSON_UNESCAPED_UNICODE);
|
|
file_put_contents($this->idsFile, print_r($idStr, true));
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
//运行
|
|
Worker::runAll();
|
|
|