webserver.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. require_once dirname(dirname(__FILE__)) . '/vendor/workerman/Autoloader.php'; //自动加载类
  3. require_once __DIR__ . '/config.php'; //配置文件
  4. use Workerman\Worker; //worker类
  5. use Workerman\Lib\Timer; //定时器函数
  6. //初始化 创建 websocket 服务器
  7. $workerWs = new Worker("websocket://127.0.0.1:12380");
  8. $workerWs->name = "WebSocket"; //命名为WebSocket
  9. // 心跳检测的实现
  10. $workerWs->onWorkerStart = function ($workerWs) {
  11. Timer::add(1, function () use ($workerWs) {
  12. $time_now = time();
  13. foreach ($workerWs->connections as $connection) {
  14. // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
  15. if (empty($connection->lastMessageTime)) {
  16. $connection->lastMessageTime = $time_now;
  17. continue;
  18. }
  19. //上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
  20. if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
  21. $connection->close();
  22. }
  23. }
  24. });
  25. };
  26. // 服务器收到信息后执行
  27. $workerWs->onMessage = function ($connection, $data) {
  28. $connection->lastMessageTime = time(); //最后的信息时间
  29. $bufExplode = explode("\r\n", $data); //通过指定的分隔符,把字符串打散为数组
  30. foreach ($bufExplode as $key => $value) {
  31. $msg = json_decode($value, true); //解析数据
  32. if ($msg) {
  33. switch ($msg['type']) {
  34. case "heartbeat": //心跳检测(前端的心跳检测)
  35. $results['type'] = 'heartbeat';
  36. $results['data'] = 'I heard';
  37. $connection->send(json_encode($results) . "\r\n");
  38. break;
  39. case "login": //异步客户端的登录(标识身份)
  40. $connection->uid = $msg['uid'];
  41. break;
  42. // 从前端传递过来的数据 开始位置======================================================================
  43. case "vue_get_order_record": //查询当前跟单订单
  44. sendToTcp([
  45. 'type' => 'get_order_record',
  46. 'order' => $msg['orderid']
  47. ]);
  48. break;
  49. case "vue_set_current_order": //设置当前跟单订单信息
  50. sendToTcp([
  51. 'type' => 'set_current_order',
  52. 'order' => (int)$msg['orderid']
  53. ]);
  54. break;
  55. case "vue_insert": //插入发送内容
  56. sendToTcp([
  57. 'type' => 'insert',
  58. 'orderid' => $msg['orderid'],
  59. 'data'=> $msg['data'],
  60. ]);
  61. break;
  62. case "vue_rollback": //Rollback请求
  63. sendToTcp([
  64. 'type' => 'rollback',
  65. 'data'=> $msg['data'],
  66. ]);
  67. break;
  68. case "vue_except_rollback": //Rollback请求
  69. sendToTcp([
  70. 'type' => 'except_rollback',
  71. 'data'=> $msg['data'],
  72. ]);
  73. break;
  74. case "vue_retry": //Retry请求
  75. sendToTcp([
  76. 'type' => 'retry',
  77. 'data'=> $msg['data'],
  78. ]);
  79. break;
  80. //从前端传递过来的数据 结束位置==================================================================
  81. //从接口过来的数据 开始位置================(这里的数据是一条一条返回的)==============================================
  82. case "get_order_record": //查询当前跟单订单
  83. sendToWeb([
  84. 'type' => $msg['type'],
  85. 'err_code' => $msg['err_code'],
  86. 'login' => $msg['login'],
  87. 'order' => $msg['order'],
  88. 'symbol' => $msg['symbol'],
  89. 'digit' => $msg['digit'],
  90. 'volume' => $msg['volume'],
  91. 'open_time' => $msg['open_time'],
  92. 'open_price' => $msg['open_price'],
  93. 'close_time' => $msg['close_time'],
  94. 'close_price'=> $msg['close_price'],
  95. 'sl' => $msg['sl'],
  96. 'tp' => $msg['tp'],
  97. 'profit' => $msg['profit'],
  98. 'commission' => $msg['commission'],
  99. 'swap' => $msg['swap'],
  100. 'comment' => $msg['comment'],
  101. ]);
  102. break;
  103. case "set_current_order": //设置当前跟单订单信息
  104. sendToWeb([
  105. 'type' => $msg['type'],
  106. 'error_code' => $msg['error_code']
  107. ]);
  108. break;
  109. case "insert": //插入发送内容
  110. sendToWeb([
  111. 'type' => $msg['type'],
  112. 'orig_order' => $msg['orig_order'],
  113. 'orig_login' => $msg['orig_login'],
  114. 'dest' => $msg['dest']
  115. ]);
  116. break;
  117. case "rollback": //Rollback请求
  118. sendToWeb([
  119. 'type' => $msg['type'],
  120. 'orig_order' => $msg['orig_order'],
  121. 'orig_login' => $msg['orig_login'],
  122. 'desc' => $msg['desc']
  123. ]);
  124. break;
  125. case "except_rollback": //retry表中 Rollback请求
  126. sendToWeb([
  127. 'type' => $msg['type'],
  128. 'orig_order' => $msg['orig_order'],
  129. 'orig_login' => $msg['orig_login'],
  130. 'dest_login' => $msg['dest_login'],
  131. 'dest_order' => $msg['dest_order'],
  132. 'error_code' => $msg['error_code'],
  133. 'profit' => $msg['profit'],
  134. 'percentage' => $msg['percentage'],
  135. ]);
  136. break;
  137. case "retry": //Retry请求
  138. sendToWeb([
  139. 'type' => $msg['type'],
  140. 'orig_order' => $msg['orig_order'], //最初的订单
  141. 'orig_login' => $msg['orig_login'], //最初的login
  142. 'dest_login' => $msg['dest_login'], //指定login
  143. 'dest_order' => $msg['dest_order'], //指定订单
  144. 'profit' => $msg['profit'], //利润点
  145. 'error_code' => $msg['error_code'], //状态码
  146. 'percentage' => $msg['percentage'], //手续费
  147. ]);
  148. break;
  149. //从接口过来的数据 结束位置========================(这里的数据是一条一条返回的)==============================================
  150. default:
  151. $results['type'] = 'info';
  152. $results['data'] = '未知类型';
  153. $connection->send(json_encode($results) . "\r\n");
  154. break;
  155. }
  156. } else {
  157. // 没有信息的时候
  158. $results['type'] = 'info';
  159. $results['data'] = 'json格式错误';
  160. $connection->send(json_encode($results) . "\r\n");
  161. }
  162. }
  163. };
  164. // 向所有的web用户发送 ( vue前端的 客户端 这里的客户端是没有uid的)
  165. function sendToWeb($msg)
  166. {
  167. global $workerWs;
  168. foreach ($workerWs->connections as $connection) {
  169. if (!isset($connection->uid)) {
  170. echo "返回给前端的数据";
  171. var_dump($msg);
  172. $connection->send(json_encode($msg) . "\r\n");
  173. }
  174. }
  175. }
  176. // 向本机的tcp服务器发送请求(tcp上有一个异步请求的客户端 他登陆是有uid字段的赋值的 )
  177. function sendToTcp($msg)
  178. {
  179. global $workerWs;
  180. foreach ($workerWs->connections as $connection) {
  181. if (isset($connection->uid) && $connection->uid == "tcp") { //只针对特定的用户发起请求
  182. echo "发送的数据";
  183. var_dump($msg);
  184. $connection->send(json_encode($msg) . "\r\n");
  185. }
  186. }
  187. }
  188. Worker::runAll(); //执行函数