imsocket.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace app\api\imsocket;
  3. use GatewayWorker\Lib\DbConnection;
  4. use think\facade\Db;
  5. use think\worker\Server;
  6. use GatewayWorker\Lib\Gateway;
  7. class imsocket extends Server
  8. {
  9. protected $socket = 'websocket://0.0.0.0:2345';
  10. protected $uidConnnections = array();
  11. public function __construct()
  12. {
  13. parent::__construct();
  14. }
  15. public function onConnect($connection){
  16. $msg=['type'=>'conn','msg'=>'连接服务器成功'];
  17. $connection->send(json_encode($msg));
  18. }
  19. public function onMessage($connection,$data)
  20. {
  21. $arr = json_decode($data);
  22. //绑定用户
  23. if($arr->type == "bind" && !isset($connection->uid)){
  24. $connection->uid = $arr->uid;
  25. //保存uid到connection的映射,实现针对特定uid的推送
  26. $this->worker->uidConnections[$connection->uid]=$connection;
  27. if($arr->school_id){
  28. //如果是学校的话,返回一个老师的id给他。
  29. $teacherList=Db::table('yoshop_user_info')
  30. ->alias('i')
  31. ->join('yoshop_user u','i.user_id = u.user_id')
  32. ->where('u.user_type','=',3)
  33. ->where('u.is_delete','=',0)
  34. ->where('i.school_id','=',$arr->school_id)
  35. ->where('i.status','=',1)
  36. ->select();
  37. $tempList=[];
  38. foreach($teacherList as $list){
  39. $temp['uid']= $list['user_id'];
  40. $temp['uname']= $list['real_name'];
  41. $temp['utype']= $list['user_type'];
  42. if(isset($this->worker->uidConnections[$list['user_id']])){
  43. //是否在线,在线加权重
  44. $temp['w']=1;
  45. }else{
  46. $temp['w']=0;
  47. }
  48. $tempList[]=$temp;
  49. }
  50. //按权重随机返回
  51. $weight = 0;
  52. $tempdata = array ();
  53. foreach ($tempList as $one) {
  54. $weight += $one['w'];
  55. for ($i = 0; $i < $one['w']; $i++) {
  56. $tempdata[] = $one;
  57. }
  58. }
  59. $use = rand(0, $weight -1);
  60. $one = $tempdata[$use];
  61. $msg=['type'=>'bind','fansinfo'=>['uid'=>$one['uid'],'uname'=>$one['uname']]];
  62. $connection->send(json_encode($msg));
  63. }
  64. }
  65. //聊天
  66. if($arr->type=="text"){
  67. $updata=[
  68. 'from_user_id'=>$arr->from_user_id,
  69. 'to_user_id'=>$arr->to_user_id,
  70. 'message'=>$arr->msg,
  71. 'school_id'=>$arr->school_id,
  72. 'speciality_id'=>$arr->speciality_id,
  73. 'sendtime'=>$arr->sendtime,
  74. 'chat_key'=>$arr->chat_key
  75. ];
  76. if(isset($this->worker->uidConnections[$arr->to_user_id])){
  77. $conn= $this->worker->uidConnections[$arr->to_user_id];
  78. $updata['is_push']=0;
  79. $conn->send($data);
  80. }else{
  81. // //先返回给发送者错误信息
  82. // $conn2= $this->worker->uidConnections[$arr->from_user_id];
  83. // $msg=['type'=>'error','msg'=>'对方不在线'];
  84. // $conn2->send(json_encode($msg));
  85. $updata['is_push']=1;
  86. }
  87. //保存数据
  88. Db::name('imchat')->insert($updata);
  89. }
  90. //获取聊天记录
  91. if($arr->type=="loadHistory"){
  92. $tfkey=$arr->tfkey;
  93. $lastMessageTimeStamp=$arr->lastMessageTimeStamp;
  94. $from_user_id=$arr->from_user_id;
  95. $conn2= $this->worker->uidConnections[$from_user_id];
  96. $msgList=Db::name('imchat')->where('chat_key','=',$tfkey)
  97. ->where('sendtime','<',$lastMessageTimeStamp)
  98. ->field('id,from_user_id,to_user_id,message,sendtime')
  99. ->order('sendtime','desc')
  100. ->limit(2)
  101. ->select();
  102. if($msgList){
  103. $msg=['type'=>'loadHistory','mgList'=>$msgList];
  104. }else{
  105. $msg=['type'=>'loadHistory','mgList'=>''];
  106. }
  107. $conn2->send(json_encode($msg));
  108. }
  109. }
  110. public function onClose($connection){
  111. unset($this->worker->uidConnections[$connection->uid]);
  112. }
  113. }