| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- <?php
- namespace app\api\imsocket;
- use think\worker\Server;
- use Workerman\Lib\Timer;
- use workerman\workerman;
- define('HEARTBEAT_TIME', 45);
- class imsocket extends Server
- {
- protected $socket = 'websocket://0.0.0.0:6541';
- protected $uidConnnections = array();
- protected $connectionUid;
- public function __construct()
- {
- parent::__construct();
- }
- public function onConnect($connection){
- $msg=['type'=>'conn','msg'=>'连接服务器成功'];
- $connection->send(json_encode($msg));
- }
- public function onWorkerStart($worker){
- //设置一个每5秒运转一次的定时器
- Timer::add(10, function()use($worker){
- $time_now = time();
- foreach($worker->connections as $connection) {
- // connection还没收到过音讯,则lastMessageTime设置为当前时时间
- if (empty($connection->lastConnTime)) {
- $connection->lastConnTime = $time_now;
- continue;
- }
- if ($time_now - $connection->lastConnTime > HEARTBEAT_TIME) {
- $connection->close();
- }
- }
- });
- }
- public function onMessage($connection,$data)
- {
- //给connection暂时设置一个lastConnTime属性,用来纪录上次收到音讯的时间
- $connection->lastConnTime = time();
- $arr = json_decode($data);
- $db = new \mysqli('47.112.222.163','nn2022060401','RL2rpdKdKicikFBx','nn2022060401','3306');
- $db->set_charset('utf8');
- //绑定用户
- if($arr->type == "bind" && !isset($connection->uid)){
- $connection->uid = $arr->uid;
- $this->connectionUid = $arr->uid;
- //保存uid到connection的映射,实现针对特定uid的推送
- $this->worker->uidConnections[$connection->uid]=$connection;
- if($arr->school_id){
- //如果是学校的话,返回一个老师的id给他。
- $tsql="SELECT u.user_id,u.user_type,u.real_name FROM yoshop_user_info i JOIN yoshop_user u ON i.user_id = u.user_id WHERE u.user_type=3 AND u.is_delete=0 AND i.school_id=".$arr->school_id." AND i.status=1";
- $resT=$db->query($tsql);
- if($resT->num_rows > 0) {
- $tempList=[];
- while($row = $resT->fetch_assoc()) {
- $temp['uid']= $row['user_id'];
- $temp['uname']= $row['real_name'];
- $temp['utype']= $row['user_type'];
- if(isset($this->worker->uidConnections[$row['user_id']])){
- //是否在线,在线加权重
- $temp['w']=1;
- }else{
- $temp['w']=0;
- }
- $tempList[]=$temp;
- }
- //按权重随机返回
- $weight = 0;
- $tempdata = array ();
- foreach ($tempList as $one) {
- $weight += $one['w'];
- for ($i = 0; $i < $one['w']; $i++) {
- $tempdata[] = $one;
- }
- }
- $use = rand(0, $weight -1);
- $one = $tempdata[$use];
- $msg=['type'=>'bind','fansinfo'=>['uid'=>$one['uid'],'uname'=>$one['uname']]];
- }else{
- $msg=['type'=>'bind','fansinfo'=>''];
- }
- }else{
- $msg=['type'=>'bind','fansinfo'=>''];
- }
- $connection->send(json_encode($msg));
- }
- //聊天
- if($arr->type=="text"){
- //先进库
- $insetSql="INSERT INTO yoshop_imchat (from_user_id,to_user_id,message,school_id,speciality_id,sendtime,chat_key,is_push)
- VALUES ('".$arr->from_user_id."','".$arr->to_user_id."','".$arr->msg."','".$arr->school_id."','".$arr->speciality_id."','".$arr->sendtime."','".$arr->chat_key."','1')";
- //保存数据
- $rs=$db->query($insetSql);
- $id=mysqli_insert_id($db);
- $temML['id']= $id;
- $temML['from_user_id']= $arr->from_user_id;
- $temML['to_user_id']= $arr->to_user_id;
- $temML['msg']= $arr->msg;
- $temML['school_id']= $arr->msg;
- $temML['speciality_id']= $arr->msg;
- $temML['chat_key']= $arr->chat_key;
- $temML['sendtime']= $arr->sendtime;
- $temML['type']= $arr->type;
- if(isset($this->worker->uidConnections[$arr->to_user_id])){
- $conn= $this->worker->uidConnections[$arr->to_user_id];
- $conn->send(json_encode($temML));
- }else{
- $conn= $this->worker->uidConnections[$arr->from_user_id];
- $conn->send(json_encode(['type'=>'down','msg'=>'对方不在线']));
- }
- }
- //在线更新已读消息
- if($arr->type=='readly'){
- $readSql="UPDATE yoshop_imchat SET is_push=0 WHERE id =".$arr->id;
- $db->query($readSql);
- }
- //获取聊天记录
- if($arr->type=="loadHistory"){
- $tfkey=$arr->tfkey;
- $lastMessageTimeStamp=$arr->lastMessageTimeStamp;
- $from_user_id=$arr->from_user_id;
- $conn2= $this->worker->uidConnections[$from_user_id];
- $mlistSql="select id,from_user_id,to_user_id,message,sendtime,is_push from yoshop_imchat where chat_key=$tfkey and sendtime < $lastMessageTimeStamp order by sendtime desc limit 10";
- $resML = $db->query($mlistSql);
- if($resML->num_rows > 0) {
- $msgList=[];
- //处理一下 未读变已读
- $push_id='';
- while($row = $resML->fetch_assoc()) {
- $temML['id']= $row['id'];
- $temML['from_user_id']= $row['from_user_id'];
- $temML['to_user_id']= $row['to_user_id'];
- $temML['message']= $row['message'];
- $temML['sendtime']= $row['sendtime'];
- if($row['is_push']==1){
- if(empty($push_id)){
- $push_id=$row['id'];
- }else{
- $push_id=$push_id .','.$row['id'];
- }
- }
- $msgList[]=$temML;
- }
- //更新未读变已读
- $upSql="UPDATE yoshop_imchat SET is_push=0 WHERE id IN(".$push_id.");";
- $db->query($upSql);
- $msg=['type'=>'loadHistory','mgList'=>$msgList];
- }else{
- $msg=['type'=>'loadHistory','mgList'=>''];
- }
- $conn2->send(json_encode($msg));
- }
- $db->close();
- }
- public function onClose($connection){
- unset($this->worker->uidConnnections[$this->connectionUid]);
- $connection->send(json_encode(['type'=>'all','msg'=>'用户'.$this->connectionUid.'已经下线']));
- $this->connectionUid='';
- }
- }
|