serv = new \swoole_websocket_server("0.0.0.0", 8090); $this->serv->set(array( 'worker_num' => 8, 'daemonize' => false, 'max_request' => 10000, 'dispatch_mode' => 2, 'debug_mode' => 1 )); $this->serv->on('Open', array($this, 'onOpen')); $this->serv->on('Message', array($this, 'onMessage')); $this->serv->on('Close', array($this, 'onClose')); $this->serv->start(); } public function onOpen($server, $request){ $chatData = []; if(empty($request->get['uid']) || empty($request->get['to_id'])){ $chatData['error'] = -1; $chatData['msg'] = '参数缺失'; $this->serv->push($request->fd, json_encode($chatData)); //推送到发送者 return ; } $this->initChatHostory($request->fd ,$request->get['uid'],$request->get['to_id']); } public function onMessage($server, $frame){ $pData = json_decode($frame->data); // var_dump($pData); $data = array(); if(!empty($pData->fid) && !empty($pData->tid) && !empty($pData->initType)){ $this->initChatHostory($frame->fd ,$pData->fid,$pData->tid); return ; } if(empty($pData->fid) || empty($pData->tid) || empty($pData->content)){ $data['error'] = -1; $data['msg'] = '参数缺失'; $data['messType'] = -1; $this->serv->push($frame->fd, json_encode($data)); //推送到发送者 return ; } $tfd = $this->getFd($pData->fid); //获取绑定的fd if(empty($tfd)){ $this->bind($pData->fid ,$frame->fd); } if($tfd != $frame->fd && !$this->updateFd($pData->fid ,$frame->fd)){ $data['error'] = -1; $data['msg'] = 'fd绑定失败'; $data['messType'] = -1; $this->serv->push($frame->fd, json_encode($data)); //推送到发送者 } $data['contentList'] = $this->add($pData->fid , $pData->tid,$pData->content)[0]; $data['send_id_info'] = $this->getInfoById($pData->fid); $data['to_id_info'] = $this->getInfoById($pData->tid); $data['messType'] = 2; $getFdByToId = $this->getFd($pData->tid); $pushFdList = []; if($getFdByToId){ array_push($pushFdList,$getFdByToId); } $pushFdList[] = $frame->fd; foreach ($pushFdList as $value){ $this->serv->push($value, json_encode($data)); //推送到发送者 } } public function onClose($server, $fd){ $this->unBind($fd); // echo "connection close: " . $fd; } public function initChatHostory($fd ,$uid ,$to_id){ $getUserFd = $this->getFd($uid); if($getUserFd){ $this->updateFd($uid,$fd); } $chatData['contentList'] = $this->loadHistory($uid, $to_id); $chatData['send_id_info'] = $this->getInfoById($uid); $chatData['to_id_info'] = $this->getInfoById($to_id); $chatData['messType'] = 1; $this->serv->push($fd, json_encode($chatData)); } public function add($fid, $tid, $content){ $chatModel = new \backend\models\Chat(); $chatModel->send_id = $fid; $chatModel->to_id = $tid; $chatModel->content = $content; $chatModel->create_time = time(); $chatModel->update_time = time(); if ($chatModel->save()) { $id = $chatModel->id; $data = $this->loadHistory($fid, $tid, $id); return $data; } else { return []; } } public function updateFd($uid ,$fd){ $result = BindFd::find()->where(['uid'=>$uid])->one(); $result->fd = $fd; return $result->save(); } public function bind($uid, $fd){ var_dump('进入bind-'.$fd); $bindFdModel = new BindFd(); $bindFdModel->uid = $uid; $bindFdModel->fd = $fd; if ($bindFdModel->save()) { return true; } return false; } public function getFd($uid){ $bindFdData = BindFd::find()->select(['fd'])->where(['uid' => $uid])->asArray()->one(); return !empty($bindFdData )? $bindFdData['fd'] : 0; } public function getInfoById($id){ $result = User::find()->select(['id','head_img','nick','username'])->where(['id' => $id])->asArray()->one(); return !empty($result) ? $result : ''; } public function unBind($fd, $uid = null){ var_dump('进入unbind-'.$fd); $where = ''; if ($uid) { $where = ['uid' => $uid]; } else { $where = ['fd' => $fd]; } $result = \Yii::$app->db->createCommand()->delete('phpfire_fd', $where)->execute(); } public function loadHistory($fid, $tid, $id = null){ $and = $id ? " and id=$id" : ''; $sql = "select send_id,content,to_id,create_time from phpfire_chat where ((send_id = $fid and to_id = $tid) or (to_id=$fid and send_id = $tid))" . $and; $data = []; $data = \backend\models\Chat::findBySql($sql)->asArray()->all(); return $data; } }