factory_processor.php 8.3 KB

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