mFactory = new factory(); $this->mRoomPos = 0; $this->mAccUniquer = new uniquer(); $this->mBufidRooms = []; } public function onStart() { global $config; $room_addrs = $config['room_factory']['rooms_addr']; foreach ($room_addrs as $addr) { process_looper::instance()->connect($addr['host'],$addr['port'],self::room_connection); } } public function onConnected($bufid,$stream,$host,$port,$args) { if($args == self::room_connection) { Log::record("room srv bufid={$bufid}",Log::DEBUG); $client = new room_client($host,$port,$stream,false); $this->mBufidRooms[$bufid] = $client; $this->block($bufid); $client->init_rooms($bufid); $this->unblock($bufid); } } public function onClose($bufid) { //if access connection if($this->mAccUniquer->remove_value($bufid)) return; //if room connection if(array_key_exists($bufid,$this->mBufidRooms)) { $client = $this->mBufidRooms[$bufid]; $addr = $client->host_port(); unset($this->mBufidRooms[$bufid]); process_looper::instance()->connect($addr['host'],$addr['port'],self::room_connection); } } private function block($bufid) { process_looper::instance()->block($bufid); } private function unblock($bufid) { process_looper::instance()->unblock($bufid); } public function onRequest($bufid, $body) { $trace = new scope_trace(__METHOD__); $input = json_decode($body,true); if($input == false) { return false; } $act = $input['act']; if(empty($act)) return false; if($act == proto_type::act_fcgi) { $ret = $this->onFcgi($bufid,$input); process_looper::instance()->write($bufid,$ret); return true; } elseif($act == proto_type::act_access) { $ret = $this->onAccess($bufid,$input); process_looper::instance()->write($bufid,$ret); return true; } else { return false; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function onFcgi($bufid, $input) { $op = $input['op']; if($op == 'create') { $ret = $this->mFactory->create($input,$fnew); if($ret != false) { $invite = $input['invite']; if($invite) { $roomid = $ret['room']; $inviter = $ret['creator']; if($roomid <= 0 || $inviter <= 0) { return $this->error(errcode::ErrRoomCreate); } if($this->build($roomid,$fnew) == false) { return $this->error(errcode::ErrRoomBuild); } $result = $this->invite($roomid,$inviter,[$inviter]); if($result != false) { $ret = array_merge($ret,$result); return $this->success($ret); } else { return $this->error(errcode::ErrRoomInvite); } } else { return $this->error(errcode::ErrRoomCreate); } } return $this->error(errcode::ErrRoomCreate); } elseif($op == 'invite') { $roomid = intval($input['room']); $inviter = intval($input['inviter']); $invitees = $input['invitees']; if($roomid <= 0 || $inviter <= 0 || empty($invitees)) { return $this->error(errcode::ErrRoomInvite); } $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } $ret = $this->invite($roomid,$inviter,$invitees); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomInvite); } } elseif($op == 'change') { $roomid = intval($input['room']); if($roomid <= 0) { return $this->error(errcode::ErrRoomChange); } $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } $ret = $this->change($roomid); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomChange); } } elseif($op == 'leave') { $roomid = intval($input['room']); $user = intval($input['user']); if($roomid <= 0 || $user <= 0) { return $this->error(errcode::ErrRoomLeave); } $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } $ret = $this->leave($roomid,$user); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomLeave); } } elseif($op == 'kickout') { $roomid = intval($input['room']); $user = intval($input['user']); $kicks = $input['kicks']; if($roomid <= 0 || $user <= 0) { return $this->error(errcode::ErrRoomKickout); } $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } $ret = $this->kickout($roomid,$user,$kicks); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomKickout); } } elseif ($op == 'notice_room') { $roomid = intval($input['room']); $type = $input['type']; $content = $input['content']; $user = $input['user']; if($roomid <= 0 || empty($content)) { return $this->error(errcode::ErrRoomNotice); } $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } $ret = $this->notice_room($roomid,$type,$content,$user); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomKickout); } } elseif($op == 'notice_all') { $content = $input['content']; $type = $input['type']; $msg = $input['msg']; $ret = $this->notice_all($type,$content,$msg); if($ret != false) { return $this->success(NULL); } else { return $this->error(errcode::ErrRoomPush); } } elseif($op == 'notice_users') { $content = $input['content']; $type = $input['type']; $users = $input['users']; $msg = $input['msg']; $ret = $this->notice_users($users,$type,$content,$msg); if($ret != false) { return $this->success(NULL); } else { return $this->error(errcode::ErrRoomPush); } } else { return $this->error(errcode::ErrRoomFactoryOp); } } private function onAccess($bufid,$input) { $op = $input['op']; if($op == 'who') { $this->mAccUniquer->add_value($bufid); return $this->success(['act' => proto_type::act_access,'op' => 'who']); } elseif($op == 'build') { $roomid = intval($input['room']); $client = $this->find_room($roomid,$bufid); if($client == false) { $this->build($roomid); } return $this->success(['act' => proto_type::act_access,'op' => $op,'room' => $roomid]); } else { return $this->error(errcode::ErrParamter); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function find_room($roomid,&$outbufid) { foreach ($this->mBufidRooms as $bufid => $client) { if($client->contain_room($roomid)) { $outbufid = $bufid; return $client; } } return false; } private function build($roomid,$newroom = false) { $client = $this->find_room($roomid,$bufid); if($client != false) { $this->block($bufid); $ret = $client->build($roomid,$newroom); $this->unblock($bufid); return $ret; } $bufid = $this->room_bufid(); if($bufid != false) { $client = $this->mBufidRooms[$bufid]; $this->block($bufid); $ret = $client->build($roomid,$newroom); $this->unblock($bufid); if($ret != false) { $client->add_room($roomid); } return $ret; } else { return false; } } private function invite($roomid, $inviter,$invitees) { $client = $this->find_room($roomid,$bufid); if($client != false) { $this->block($bufid); $ret = $client->invite($roomid,$inviter,$invitees); $this->unblock($bufid); return $ret; } return false; } private function change($roomid) { $client = $this->find_room($roomid,$bufid); if($client != false) { $this->block($bufid); $ret = $client->change($roomid); $this->unblock($bufid); return $ret; } return false; } private function leave($roomid, $user) { foreach ($this->mBufidRooms as $bufid => $client) { if($client->contain_room($roomid)) { $this->block($bufid); $ret = $client->leave($roomid,$user); $this->unblock($bufid); return $ret; } } } private function kickout($roomid, $user,$kicks) { foreach ($this->mBufidRooms as $bufid => $client) { if($client->contain_room($roomid)) { $this->block($bufid); $ret = $client->kickout($roomid,$user,$kicks); $this->unblock($bufid); return $ret; } } } private function notice_room($roomid,$type,$content,$user) { foreach ($this->mBufidRooms as $bufid => $client) { if($client->contain_room($roomid)) { $this->block($bufid); $ret = $client->notice_room($roomid,$type,$content,$user); $this->unblock($bufid); return $ret; } } } private function notice_all($type,$content,$msg) { $bufid = $this->room_bufid(); if($bufid != false) { $client = $this->mBufidRooms[$bufid]; $this->block($bufid); $client->notice_all($type,$content,$msg); $this->unblock($bufid); return true; } return false; } private function notice_users($users,$type,$content,$msg) { $bufid = $this->room_bufid(); if($bufid != false) { $client = $this->mBufidRooms[$bufid]; $this->block($bufid); $client->notice_users($users,$type,$content,$msg); $this->unblock($bufid); return true; } return false; } private function room_bufid() { $count = count($this->mBufidRooms); if($count <= 0) return false; $pos = $this->mRoomPos % $count; $i = 0; foreach ($this->mBufidRooms as $bufid => $client) { if($i == $pos) break; $pos++; } $this->mRoomPos++; Log::record("select bufid = {$bufid}",Log::DEBUG); return $bufid; } private function success($datas) { $code = errcode::Success; $data['code'] = $code; $data['message'] = errcode::msg($code); $data['data'] = $datas; $data['msgtype'] = "reply"; return json_encode($data); } private function error($code,$message = '') { if (empty($message)) { $message = errcode::msg($code); } $data['code'] = $code; $data['message'] = $message; $data['datas'] = null; $data['msgtype'] = "reply"; return json_encode($data); } }