Base.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. /**
  3. * This file is part of workerman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Workerman\Events\React;
  15. use Workerman\Events\EventInterface;
  16. use React\EventLoop\TimerInterface;
  17. use React\EventLoop\LoopInterface;
  18. /**
  19. * Class StreamSelectLoop
  20. * @package Workerman\Events\React
  21. */
  22. class Base implements LoopInterface
  23. {
  24. /**
  25. * @var array
  26. */
  27. protected $_timerIdMap = array();
  28. /**
  29. * @var int
  30. */
  31. protected $_timerIdIndex = 0;
  32. /**
  33. * @var array
  34. */
  35. protected $_signalHandlerMap = array();
  36. /**
  37. * @var LoopInterface
  38. */
  39. protected $_eventLoop = null;
  40. /**
  41. * Base constructor.
  42. */
  43. public function __construct()
  44. {
  45. $this->_eventLoop = new \React\EventLoop\StreamSelectLoop();
  46. }
  47. /**
  48. * Add event listener to event loop.
  49. *
  50. * @param int $fd
  51. * @param int $flag
  52. * @param callable $func
  53. * @param array $args
  54. * @return bool
  55. */
  56. public function add($fd, $flag, $func, array $args = array())
  57. {
  58. $args = (array)$args;
  59. switch ($flag) {
  60. case EventInterface::EV_READ:
  61. return $this->addReadStream($fd, $func);
  62. case EventInterface::EV_WRITE:
  63. return $this->addWriteStream($fd, $func);
  64. case EventInterface::EV_SIGNAL:
  65. if (isset($this->_signalHandlerMap[$fd])) {
  66. $this->removeSignal($fd, $this->_signalHandlerMap[$fd]);
  67. }
  68. $this->_signalHandlerMap[$fd] = $func;
  69. return $this->addSignal($fd, $func);
  70. case EventInterface::EV_TIMER:
  71. $timer_obj = $this->addPeriodicTimer($fd, function() use ($func, $args) {
  72. \call_user_func_array($func, $args);
  73. });
  74. $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
  75. return $this->_timerIdIndex;
  76. case EventInterface::EV_TIMER_ONCE:
  77. $index = ++$this->_timerIdIndex;
  78. $timer_obj = $this->addTimer($fd, function() use ($func, $args, $index) {
  79. $this->del($index,EventInterface::EV_TIMER_ONCE);
  80. \call_user_func_array($func, $args);
  81. });
  82. $this->_timerIdMap[$index] = $timer_obj;
  83. return $this->_timerIdIndex;
  84. }
  85. return false;
  86. }
  87. /**
  88. * Remove event listener from event loop.
  89. *
  90. * @param mixed $fd
  91. * @param int $flag
  92. * @return bool
  93. */
  94. public function del($fd, $flag)
  95. {
  96. switch ($flag) {
  97. case EventInterface::EV_READ:
  98. return $this->removeReadStream($fd);
  99. case EventInterface::EV_WRITE:
  100. return $this->removeWriteStream($fd);
  101. case EventInterface::EV_SIGNAL:
  102. if (!isset($this->_eventLoop[$fd])) {
  103. return false;
  104. }
  105. $func = $this->_eventLoop[$fd];
  106. unset($this->_eventLoop[$fd]);
  107. return $this->removeSignal($fd, $func);
  108. case EventInterface::EV_TIMER:
  109. case EventInterface::EV_TIMER_ONCE:
  110. if (isset($this->_timerIdMap[$fd])){
  111. $timer_obj = $this->_timerIdMap[$fd];
  112. unset($this->_timerIdMap[$fd]);
  113. $this->cancelTimer($timer_obj);
  114. return true;
  115. }
  116. }
  117. return false;
  118. }
  119. /**
  120. * Main loop.
  121. *
  122. * @return void
  123. */
  124. public function loop()
  125. {
  126. $this->run();
  127. }
  128. /**
  129. * Destroy loop.
  130. *
  131. * @return void
  132. */
  133. public function destroy()
  134. {
  135. }
  136. /**
  137. * Get timer count.
  138. *
  139. * @return integer
  140. */
  141. public function getTimerCount()
  142. {
  143. return \count($this->_timerIdMap);
  144. }
  145. /**
  146. * @param resource $stream
  147. * @param callable $listener
  148. */
  149. public function addReadStream($stream, $listener)
  150. {
  151. return $this->_eventLoop->addReadStream($stream, $listener);
  152. }
  153. /**
  154. * @param resource $stream
  155. * @param callable $listener
  156. */
  157. public function addWriteStream($stream, $listener)
  158. {
  159. return $this->_eventLoop->addWriteStream($stream, $listener);
  160. }
  161. /**
  162. * @param resource $stream
  163. */
  164. public function removeReadStream($stream)
  165. {
  166. return $this->_eventLoop->removeReadStream($stream);
  167. }
  168. /**
  169. * @param resource $stream
  170. */
  171. public function removeWriteStream($stream)
  172. {
  173. return $this->_eventLoop->removeWriteStream($stream);
  174. }
  175. /**
  176. * @param float|int $interval
  177. * @param callable $callback
  178. * @return \React\EventLoop\Timer\Timer|TimerInterface
  179. */
  180. public function addTimer($interval, $callback)
  181. {
  182. return $this->_eventLoop->addTimer($interval, $callback);
  183. }
  184. /**
  185. * @param float|int $interval
  186. * @param callable $callback
  187. * @return \React\EventLoop\Timer\Timer|TimerInterface
  188. */
  189. public function addPeriodicTimer($interval, $callback)
  190. {
  191. return $this->_eventLoop->addPeriodicTimer($interval, $callback);
  192. }
  193. /**
  194. * @param TimerInterface $timer
  195. */
  196. public function cancelTimer(TimerInterface $timer)
  197. {
  198. return $this->_eventLoop->cancelTimer($timer);
  199. }
  200. /**
  201. * @param callable $listener
  202. */
  203. public function futureTick($listener)
  204. {
  205. return $this->_eventLoop->futureTick($listener);
  206. }
  207. /**
  208. * @param int $signal
  209. * @param callable $listener
  210. */
  211. public function addSignal($signal, $listener)
  212. {
  213. return $this->_eventLoop->addSignal($signal, $listener);
  214. }
  215. /**
  216. * @param int $signal
  217. * @param callable $listener
  218. */
  219. public function removeSignal($signal, $listener)
  220. {
  221. return $this->_eventLoop->removeSignal($signal, $listener);
  222. }
  223. /**
  224. * Run.
  225. */
  226. public function run()
  227. {
  228. return $this->_eventLoop->run();
  229. }
  230. /**
  231. * Stop.
  232. */
  233. public function stop()
  234. {
  235. return $this->_eventLoop->stop();
  236. }
  237. }