factory_processor.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2017/12/14
  6. * Time: 下午12:07
  7. */
  8. namespace room;
  9. use event\IProcessor;
  10. use process_looper;
  11. use errcode;
  12. use uniquer;
  13. class factory_processor implements IProcessor
  14. {
  15. const room_connection = "room_connection";
  16. private $mFactory;
  17. private $mLastBuilding;
  18. private $mAccUniquer;
  19. private $mBufidRooms;
  20. public function __construct()
  21. {
  22. $this->mFactory = new factory();
  23. $this->mLastBuilding = 0;
  24. $this->mAccUniquer = new uniquer();
  25. $this->mBufidRooms = [];
  26. }
  27. public function onStart()
  28. {
  29. global $config;
  30. $room_addrs = $config['room_factory']['rooms_addr'];
  31. foreach ($room_addrs as $addr) {
  32. process_looper::instance()->connect($addr['host'],$addr['port'],self::room_connection);
  33. }
  34. }
  35. public function onConnected($bufid,$stream,$host,$port,$args)
  36. {
  37. if($args == self::room_connection) {
  38. $client = new room_client($host,$port,$stream,false);
  39. $this->mBufidRooms[$bufid] = $client;
  40. $this->block($bufid);
  41. $client->init_rooms($bufid);
  42. $this->unblock($bufid);
  43. }
  44. }
  45. public function onClose($bufid)
  46. {
  47. //if access connection
  48. if($this->mAccUniquer->remove_value($bufid)) return;
  49. //if room connection
  50. if(array_key_exists($bufid,$this->mBufidRooms)) {
  51. $client = $this->mBufidRooms[$bufid];
  52. $addr = $client->host_port();
  53. unset($this->mBufidRooms[$bufid]);
  54. process_looper::instance()->connect($addr['host'],$addr['port'],self::room_connection);
  55. }
  56. }
  57. private function block($bufid) {
  58. process_looper::instance()->block($bufid);
  59. }
  60. private function unblock($bufid) {
  61. process_looper::instance()->unblock($bufid);
  62. }
  63. public function onRequest($bufid, $body)
  64. {
  65. $input = json_decode($body,true);
  66. if($input == false) {
  67. return false;
  68. }
  69. $act = $input['act'];
  70. if(empty($act)) return false;
  71. if($act == proto_type::act_fcgi) {
  72. $ret = $this->onFcgi($bufid,$input);
  73. process_looper::instance()->write($bufid,$ret);
  74. return true;
  75. }
  76. elseif($act == proto_type::act_access) {
  77. $ret = $this->onAccess($bufid,$input);
  78. process_looper::instance()->write($bufid,$ret);
  79. return true;
  80. }
  81. else {
  82. return false;
  83. }
  84. }
  85. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  86. private function onFcgi($bufid, $input)
  87. {
  88. $op = $input['op'];
  89. if($op == 'create')
  90. {
  91. $ret = $this->mFactory->create($input);
  92. if($ret != false)
  93. {
  94. $invite = $input['invite'];
  95. if($invite)
  96. {
  97. $roomid = $ret['room'];
  98. $inviter = $ret['creator'];
  99. if($roomid <= 0 || $inviter <= 0) {
  100. return $this->error(errcode::ErrRoomCreate);
  101. }
  102. $result = $this->invite($roomid,$inviter,[$inviter]);
  103. if($result != false) {
  104. $ret = array_merge($ret,$result);
  105. return $this->success($ret);
  106. } else {
  107. return $this->error(errcode::ErrRoomInvite);
  108. }
  109. }
  110. else {
  111. return $this->success($ret);
  112. }
  113. }
  114. return $this->error(errcode::ErrRoomCreate);
  115. }
  116. elseif($op == 'invite')
  117. {
  118. $roomid = intval($input['room']);
  119. $inviter = intval($input['inviter']);
  120. $invitees = $input['invitees'];
  121. if($roomid <= 0 || $inviter <= 0 || empty($invitees)) {
  122. return $this->error(errcode::ErrRoomInvite);
  123. }
  124. $ret = $this->invite($roomid,$inviter,$invitees);
  125. if($ret != false) {
  126. return $this->success($ret);
  127. } else {
  128. return $this->error(errcode::ErrRoomInvite);
  129. }
  130. }
  131. elseif($op == 'leave')
  132. {
  133. $roomid = intval($input['room']);
  134. $user = intval($input['user']);
  135. if($roomid <= 0 || $user <= 0) {
  136. return $this->error(errcode::ErrRoomInvite);
  137. }
  138. $ret = $this->leave($roomid,$user);
  139. if($ret != false) {
  140. return $this->success($ret);
  141. } else {
  142. return $this->error(errcode::ErrRoomInvite);
  143. }
  144. }
  145. elseif($op == 'push')
  146. {
  147. $content = $input['content'];
  148. $ret = $this->push($content);
  149. if($ret != false) {
  150. return $this->success(NULL);
  151. } else {
  152. return $this->error(errcode::ErrRoomPush);
  153. }
  154. }
  155. else {
  156. return $this->error(errcode::ErrRoomFactoryOp);
  157. }
  158. }
  159. private function onAccess($bufid,$input)
  160. {
  161. $op = $input['op'];
  162. if($op == 'who') {
  163. $this->mAccUniquer->add_value($bufid);
  164. return $this->success(['act' => proto_type::act_access,'op' => 'who']);
  165. }
  166. elseif($op == 'build') {
  167. $roomid = intval($input['room']);
  168. $ret = $this->build($roomid);
  169. return $this->success(['act' => proto_type::act_access,'op' => $op,'room' => $roomid]);
  170. }
  171. else {
  172. return $this->error(errcode::ErrParamter);
  173. }
  174. }
  175. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  176. private function invite($roomid, $inviter,$invitees)
  177. {
  178. foreach ($this->mBufidRooms as $bufid => $client)
  179. {
  180. if($client->contain_room($roomid))
  181. {
  182. $this->block($bufid);
  183. $ret = $client->invite($roomid,$inviter,$invitees);
  184. $this->unblock($bufid);
  185. return $ret;
  186. }
  187. }
  188. $bufid = $this->room_bufid();
  189. if($bufid != false)
  190. {
  191. $client = $this->mBufidRooms[$bufid];
  192. $this->block($bufid);
  193. $ret = $client->invite($roomid,$inviter,$invitees);
  194. $this->unblock($bufid);
  195. if($ret != false) {
  196. $client->add_room($roomid);
  197. }
  198. }
  199. return $ret;
  200. }
  201. private function build($roomid)
  202. {
  203. foreach ($this->mBufidRooms as $bufid => $client)
  204. {
  205. if($client->contain_room($roomid))
  206. {
  207. $this->block($bufid);
  208. $ret = $client->build($roomid);
  209. $this->unblock($bufid);
  210. return $ret;
  211. }
  212. }
  213. $bufid = $this->room_bufid();
  214. if($bufid != false)
  215. {
  216. $client = $this->mBufidRooms[$bufid];
  217. $this->block($bufid);
  218. $ret = $client->build($roomid);
  219. $this->unblock($bufid);
  220. if($ret != false) {
  221. $client->add_room($roomid);
  222. }
  223. return $ret;
  224. }
  225. else {
  226. return false;
  227. }
  228. }
  229. private function leave($roomid, $user)
  230. {
  231. foreach ($this->mBufidRooms as $bufid => $client)
  232. {
  233. if($client->contain_room($roomid))
  234. {
  235. $this->block($bufid);
  236. $ret = $client->leave($roomid,$user);
  237. $this->unblock($bufid);
  238. return $ret;
  239. }
  240. }
  241. }
  242. private function push($content)
  243. {
  244. $bufid = $this->room_bufid();
  245. if($bufid != false)
  246. {
  247. $client = $this->mBufidRooms[$bufid];
  248. $this->block($bufid);
  249. $ret = $client->push($content);
  250. $this->unblock($bufid);
  251. return true;
  252. }
  253. return false;
  254. }
  255. private function room_bufid()
  256. {
  257. $count = count($this->mBufidRooms);
  258. if($count <= 0) return false;
  259. if($this->mLastBuilding >= $count) {
  260. $this->mLastBuilding = 0;
  261. }
  262. $pos = 0;
  263. foreach ($this->mBufidRooms as $bufid => $client)
  264. {
  265. if($pos != $this->mLastBuilding) {
  266. $pos++;
  267. continue;
  268. }
  269. else {
  270. break;
  271. }
  272. }
  273. return $bufid;
  274. }
  275. private function success($datas)
  276. {
  277. $code = errcode::Success;
  278. $data['code'] = $code;
  279. $data['message'] = errcode::msg($code);
  280. $data['data'] = $datas;
  281. $data['msgtype'] = "reply";
  282. return json_encode($data);
  283. }
  284. private function error($code,$message = '')
  285. {
  286. if (empty($message)) {
  287. $message = errcode::msg($code);
  288. }
  289. $data['code'] = $code;
  290. $data['message'] = $message;
  291. $data['datas'] = null;
  292. $data['msgtype'] = "reply";
  293. return json_encode($data);
  294. }
  295. }