mFactory = new factory(); $this->mLastBuilding = 0; $this->mAccUniquer = new uniquer(); $this->mBufidRooms = []; $this->init(); } private function init() { global $config; $room_addrs = $config['room_factory']['rooms_addr']; foreach ($room_addrs as $addr) { factory_server::instance()->connect($addr['host'],$addr['port'],self::room_connection); } } public function onConnected($bufid,$stream,$host,$port,$args) { new scope_trace(__METHOD__); if($args == self::room_connection) { $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) { new scope_trace(__METHOD__); //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]); factory_server::instance()->connect($addr['host'],$addr['port'],self::room_connection); } } private function block($bufid) { factory_server::instance()->block($bufid); } private function unblock($bufid) { factory_server::instance()->unblock($bufid); } public function onRequest($bufid, $body) { 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); factory_server::instance()->write($bufid,$ret); return true; } elseif($act == proto_type::act_access) { $ret = $this->onAccess($bufid,$input); factory_server::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); if($ret != false) { $invite = $input['invite']; if($invite) { $roomid = $ret['room']; $inviter = $ret['creator']; if($roomid <= 0 || $inviter <= 0) { return $this->error(errcode::ErrRoomCreate); } $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->success($ret); } } 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); } $ret = $this->invite($roomid,$inviter,$invitees); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomInvite); } } elseif($op == 'leave') { $roomid = intval($input['room']); $user = intval($input['user']); if($roomid <= 0 || $user <= 0) { return $this->error(errcode::ErrRoomInvite); } $ret = $this->leave($roomid,$user); if($ret != false) { return $this->success($ret); } else { return $this->error(errcode::ErrRoomInvite); } } elseif($op == 'push') { $content = $input['content']; $ret = $this->push($content); 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']); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function invite($roomid, $inviter,$invitees) { foreach ($this->mBufidRooms as $bufid => $client) { if($client->contain_room($roomid)) { $this->block($bufid); $ret = $client->invite($roomid,$inviter,$invitees); $this->unblock($bufid); if($ret != false) { //todo broad cast all access } return $ret; } } $bufid = $this->room_bufid(); if($bufid != false) { $client = $this->mBufidRooms[$bufid]; $this->block($bufid); $ret = $client->invite($roomid,$inviter,$invitees); $this->unblock($bufid); if($ret != false) { $client->add_room($roomid); } } return $ret; } 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); if($ret != false) { //todo broad cast all access } return $ret; } } } private function push($content) { $bufid = $this->room_bufid(); if($bufid != false) { $client = $this->mBufidRooms[$bufid]; $this->block($bufid); $ret = $client->push($content); $this->unblock($bufid); return true; } return false; } private function room_bufid() { $count = count($this->mBufidRooms); if($count <= 0) return false; if($this->mLastBuilding >= $count) { $this->mLastBuilding = 0; } $pos = 0; foreach ($this->mBufidRooms as $bufid => $client) { if($pos != $this->mLastBuilding) { $pos++; continue; } else { break; } } 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); } }