@bigtyphoon/melo 1.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +55 -0
  3. package/bin/commadtest.ts +10 -0
  4. package/bin/commands/add.ts +43 -0
  5. package/bin/commands/init.ts +292 -0
  6. package/bin/commands/kill.ts +21 -0
  7. package/bin/commands/list.ts +60 -0
  8. package/bin/commands/masterha.ts +40 -0
  9. package/bin/commands/restart.ts +48 -0
  10. package/bin/commands/start.ts +65 -0
  11. package/bin/commands/stop.ts +26 -0
  12. package/bin/melo.ts +30 -0
  13. package/bin/utils/constants.ts +27 -0
  14. package/bin/utils/utils.ts +130 -0
  15. package/dist/bin/commadtest.js +9 -0
  16. package/dist/bin/commands/add.js +40 -0
  17. package/dist/bin/commands/init.js +279 -0
  18. package/dist/bin/commands/kill.js +21 -0
  19. package/dist/bin/commands/list.js +65 -0
  20. package/dist/bin/commands/masterha.js +36 -0
  21. package/dist/bin/commands/restart.js +45 -0
  22. package/dist/bin/commands/start.js +58 -0
  23. package/dist/bin/commands/stop.js +20 -0
  24. package/dist/bin/melo.js +26 -0
  25. package/dist/bin/utils/constants.js +28 -0
  26. package/dist/bin/utils/utils.js +134 -0
  27. package/dist/lib/application.js +888 -0
  28. package/dist/lib/common/manager/appManager.js +112 -0
  29. package/dist/lib/common/manager/taskManager.js +39 -0
  30. package/dist/lib/common/remote/backend/msgRemote.js +63 -0
  31. package/dist/lib/common/remote/frontend/channelRemote.js +78 -0
  32. package/dist/lib/common/remote/frontend/sessionRemote.js +76 -0
  33. package/dist/lib/common/service/backendSessionService.js +337 -0
  34. package/dist/lib/common/service/channelService.js +514 -0
  35. package/dist/lib/common/service/connectionService.js +95 -0
  36. package/dist/lib/common/service/filterService.js +112 -0
  37. package/dist/lib/common/service/handlerService.js +187 -0
  38. package/dist/lib/common/service/sessionService.js +610 -0
  39. package/dist/lib/components/backendSession.js +14 -0
  40. package/dist/lib/components/channel.js +13 -0
  41. package/dist/lib/components/connection.js +12 -0
  42. package/dist/lib/components/connector.js +437 -0
  43. package/dist/lib/components/dictionary.js +93 -0
  44. package/dist/lib/components/master.js +39 -0
  45. package/dist/lib/components/monitor.js +25 -0
  46. package/dist/lib/components/protobuf.js +156 -0
  47. package/dist/lib/components/proxy.js +236 -0
  48. package/dist/lib/components/pushScheduler.js +62 -0
  49. package/dist/lib/components/remote.js +127 -0
  50. package/dist/lib/components/server.js +63 -0
  51. package/dist/lib/components/session.js +20 -0
  52. package/dist/lib/connectors/commands/handshake.js +119 -0
  53. package/dist/lib/connectors/commands/heartbeat.js +67 -0
  54. package/dist/lib/connectors/commands/kick.js +15 -0
  55. package/dist/lib/connectors/common/coder.js +90 -0
  56. package/dist/lib/connectors/common/handler.js +57 -0
  57. package/dist/lib/connectors/hybrid/IHybridSocket.js +3 -0
  58. package/dist/lib/connectors/hybrid/switcher.js +100 -0
  59. package/dist/lib/connectors/hybrid/tcpprocessor.js +40 -0
  60. package/dist/lib/connectors/hybrid/tcpsocket.js +171 -0
  61. package/dist/lib/connectors/hybrid/wsprocessor.js +49 -0
  62. package/dist/lib/connectors/hybridconnector.js +89 -0
  63. package/dist/lib/connectors/hybridsocket.js +139 -0
  64. package/dist/lib/connectors/mqtt/generate.js +113 -0
  65. package/dist/lib/connectors/mqtt/mqttadaptor.js +81 -0
  66. package/dist/lib/connectors/mqtt/protocol.js +48 -0
  67. package/dist/lib/connectors/mqttconnector.js +107 -0
  68. package/dist/lib/connectors/mqttsocket.js +59 -0
  69. package/dist/lib/connectors/sioconnector.js +135 -0
  70. package/dist/lib/connectors/siosocket.js +69 -0
  71. package/dist/lib/connectors/udpconnector.js +76 -0
  72. package/dist/lib/connectors/udpsocket.js +93 -0
  73. package/dist/lib/filters/handler/serial.js +44 -0
  74. package/dist/lib/filters/handler/time.js +32 -0
  75. package/dist/lib/filters/handler/timeout.js +45 -0
  76. package/dist/lib/filters/handler/toobusy.js +36 -0
  77. package/dist/lib/filters/rpc/rpcLog.js +43 -0
  78. package/dist/lib/filters/rpc/toobusy.js +41 -0
  79. package/dist/lib/index.js +81 -0
  80. package/dist/lib/interfaces/IComponent.js +3 -0
  81. package/dist/lib/interfaces/IConnector.js +3 -0
  82. package/dist/lib/interfaces/IHandlerFilter.js +3 -0
  83. package/dist/lib/interfaces/ILifeCycle.js +3 -0
  84. package/dist/lib/interfaces/IPlugin.js +3 -0
  85. package/dist/lib/interfaces/IPushScheduler.js +3 -0
  86. package/dist/lib/interfaces/ISocket.js +3 -0
  87. package/dist/lib/interfaces/IStore.js +3 -0
  88. package/dist/lib/interfaces/define.js +3 -0
  89. package/dist/lib/master/master.js +129 -0
  90. package/dist/lib/master/starter.js +236 -0
  91. package/dist/lib/master/watchdog.js +120 -0
  92. package/dist/lib/melo.js +125 -0
  93. package/dist/lib/modules/console.js +436 -0
  94. package/dist/lib/modules/masterwatcher.js +98 -0
  95. package/dist/lib/modules/monitorwatcher.js +124 -0
  96. package/dist/lib/modules/onlineUser.js +69 -0
  97. package/dist/lib/modules/restartNotifyModule.js +107 -0
  98. package/dist/lib/modules/watchServer.js +737 -0
  99. package/dist/lib/monitor/monitor.js +80 -0
  100. package/dist/lib/pushSchedulers/buffer.js +96 -0
  101. package/dist/lib/pushSchedulers/direct.js +58 -0
  102. package/dist/lib/pushSchedulers/multi.js +80 -0
  103. package/dist/lib/server/server.js +500 -0
  104. package/dist/lib/util/appUtil.js +306 -0
  105. package/dist/lib/util/constants.js +117 -0
  106. package/dist/lib/util/countDownLatch.js +51 -0
  107. package/dist/lib/util/events.js +20 -0
  108. package/dist/lib/util/handlerHelper.js +8 -0
  109. package/dist/lib/util/log.js +14 -0
  110. package/dist/lib/util/moduleUtil.js +101 -0
  111. package/dist/lib/util/pathUtil.js +134 -0
  112. package/dist/lib/util/remoterHelper.js +8 -0
  113. package/dist/lib/util/utils.js +358 -0
  114. package/dist/test/application.js +522 -0
  115. package/dist/test/config/log4js.json +28 -0
  116. package/dist/test/config/master.json +9 -0
  117. package/dist/test/config/servers.json +6 -0
  118. package/dist/test/filters/handler/serial.js +41 -0
  119. package/dist/test/filters/handler/time.js +41 -0
  120. package/dist/test/filters/handler/timeout.js +41 -0
  121. package/dist/test/filters/handler/toobusy.js +57 -0
  122. package/dist/test/filters/rpc/rpcLog.js +22 -0
  123. package/dist/test/filters/rpc/toobusy.js +39 -0
  124. package/dist/test/manager/mockChannelManager.js +77 -0
  125. package/dist/test/manager/taskManager.js +68 -0
  126. package/dist/test/mock-base/app/servers/other-file +0 -0
  127. package/dist/test/mock-plugin/components/mockPlugin.js +10 -0
  128. package/dist/test/mock-plugin/events/mockEvent.js +12 -0
  129. package/dist/test/modules/console.js +242 -0
  130. package/dist/test/pomelo.js +19 -0
  131. package/dist/test/remote/channelRemote.js +159 -0
  132. package/dist/test/service/channel.js +134 -0
  133. package/dist/test/service/channelService.js +216 -0
  134. package/dist/test/service/connectionService.js +114 -0
  135. package/dist/test/service/filterService.js +144 -0
  136. package/dist/test/service/handlerService.js +65 -0
  137. package/dist/test/service/sessionService.js +387 -0
  138. package/dist/test/util/countDownLatch.js +70 -0
  139. package/dist/test/util/pathUtil.js +108 -0
  140. package/dist/test/util/utils.js +140 -0
  141. package/lib/application.ts +1240 -0
  142. package/lib/common/manager/appManager.ts +118 -0
  143. package/lib/common/manager/taskManager.ts +50 -0
  144. package/lib/common/remote/backend/msgRemote.ts +134 -0
  145. package/lib/common/remote/frontend/channelRemote.ts +91 -0
  146. package/lib/common/remote/frontend/sessionRemote.ts +91 -0
  147. package/lib/common/service/backendSessionService.ts +388 -0
  148. package/lib/common/service/channelService.ts +609 -0
  149. package/lib/common/service/connectionService.ts +112 -0
  150. package/lib/common/service/filterService.ts +118 -0
  151. package/lib/common/service/handlerService.ts +224 -0
  152. package/lib/common/service/sessionService.ts +731 -0
  153. package/lib/components/backendSession.ts +14 -0
  154. package/lib/components/channel.ts +11 -0
  155. package/lib/components/connection.ts +13 -0
  156. package/lib/components/connector.ts +533 -0
  157. package/lib/components/dictionary.ts +121 -0
  158. package/lib/components/master.ts +41 -0
  159. package/lib/components/monitor.ts +30 -0
  160. package/lib/components/protobuf.ts +208 -0
  161. package/lib/components/proxy.ts +282 -0
  162. package/lib/components/pushScheduler.ts +70 -0
  163. package/lib/components/remote.ts +166 -0
  164. package/lib/components/server.ts +71 -0
  165. package/lib/components/session.ts +22 -0
  166. package/lib/connectors/commands/handshake.ts +155 -0
  167. package/lib/connectors/commands/heartbeat.ts +83 -0
  168. package/lib/connectors/commands/kick.ts +11 -0
  169. package/lib/connectors/common/coder.ts +93 -0
  170. package/lib/connectors/common/handler.ts +62 -0
  171. package/lib/connectors/hybrid/IHybridSocket.ts +9 -0
  172. package/lib/connectors/hybrid/switcher.ts +142 -0
  173. package/lib/connectors/hybrid/tcpprocessor.ts +43 -0
  174. package/lib/connectors/hybrid/tcpsocket.ts +223 -0
  175. package/lib/connectors/hybrid/wsprocessor.ts +57 -0
  176. package/lib/connectors/hybridconnector.ts +134 -0
  177. package/lib/connectors/hybridsocket.ts +168 -0
  178. package/lib/connectors/mqtt/generate.ts +103 -0
  179. package/lib/connectors/mqtt/mqttadaptor.ts +114 -0
  180. package/lib/connectors/mqtt/protocol.ts +49 -0
  181. package/lib/connectors/mqttconnector.ts +134 -0
  182. package/lib/connectors/mqttsocket.ts +79 -0
  183. package/lib/connectors/sioconnector.ts +161 -0
  184. package/lib/connectors/siosocket.ts +85 -0
  185. package/lib/connectors/udpconnector.ts +113 -0
  186. package/lib/connectors/udpsocket.ts +110 -0
  187. package/lib/filters/handler/serial.ts +46 -0
  188. package/lib/filters/handler/time.ts +35 -0
  189. package/lib/filters/handler/timeout.ts +50 -0
  190. package/lib/filters/handler/toobusy.ts +37 -0
  191. package/lib/filters/rpc/rpcLog.ts +42 -0
  192. package/lib/filters/rpc/toobusy.ts +41 -0
  193. package/lib/index.ts +74 -0
  194. package/lib/interfaces/IComponent.ts +47 -0
  195. package/lib/interfaces/IConnector.ts +20 -0
  196. package/lib/interfaces/IHandlerFilter.ts +15 -0
  197. package/lib/interfaces/ILifeCycle.ts +16 -0
  198. package/lib/interfaces/IPlugin.ts +65 -0
  199. package/lib/interfaces/IPushScheduler.ts +52 -0
  200. package/lib/interfaces/ISocket.ts +26 -0
  201. package/lib/interfaces/IStore.ts +10 -0
  202. package/lib/interfaces/define.ts +15 -0
  203. package/lib/master/master.ts +148 -0
  204. package/lib/master/starter.ts +234 -0
  205. package/lib/master/watchdog.ts +135 -0
  206. package/lib/melo.ts +152 -0
  207. package/lib/modules/console.ts +465 -0
  208. package/lib/modules/masterwatcher.ts +120 -0
  209. package/lib/modules/monitorwatcher.ts +151 -0
  210. package/lib/modules/onlineUser.ts +78 -0
  211. package/lib/modules/restartNotifyModule.ts +128 -0
  212. package/lib/modules/watchServer.ts +766 -0
  213. package/lib/monitor/monitor.ts +99 -0
  214. package/lib/pushSchedulers/buffer.ts +117 -0
  215. package/lib/pushSchedulers/direct.ts +65 -0
  216. package/lib/pushSchedulers/multi.ts +94 -0
  217. package/lib/server/server.ts +554 -0
  218. package/lib/util/appUtil.ts +313 -0
  219. package/lib/util/constants.ts +154 -0
  220. package/lib/util/countDownLatch.ts +72 -0
  221. package/lib/util/events.ts +15 -0
  222. package/lib/util/handlerHelper.ts +5 -0
  223. package/lib/util/log.ts +11 -0
  224. package/lib/util/moduleUtil.ts +110 -0
  225. package/lib/util/pathUtil.ts +132 -0
  226. package/lib/util/remoterHelper.ts +68 -0
  227. package/lib/util/utils.ts +365 -0
  228. package/package.json +93 -0
  229. package/template/game-server/.vscode/launch.json +27 -0
  230. package/template/game-server/app/servers/connector/handler/entryHandler.ts +50 -0
  231. package/template/game-server/app/servers/connector/remote/authRemoter.ts +36 -0
  232. package/template/game-server/app.ts +30 -0
  233. package/template/game-server/app.ts.mqtt +32 -0
  234. package/template/game-server/app.ts.sio +36 -0
  235. package/template/game-server/app.ts.sio.wss +34 -0
  236. package/template/game-server/app.ts.udp +31 -0
  237. package/template/game-server/app.ts.wss +40 -0
  238. package/template/game-server/config/adminServer.json +5 -0
  239. package/template/game-server/config/adminUser.json +22 -0
  240. package/template/game-server/config/clientProtos.json +1 -0
  241. package/template/game-server/config/dictionary.json +1 -0
  242. package/template/game-server/config/log4js.json +150 -0
  243. package/template/game-server/config/master.json +8 -0
  244. package/template/game-server/config/serverProtos.json +1 -0
  245. package/template/game-server/config/servers.json +12 -0
  246. package/template/game-server/copy.js +5 -0
  247. package/template/game-server/package.json +28 -0
  248. package/template/game-server/preload.ts +40 -0
  249. package/template/game-server/tsconfig.json +36 -0
  250. package/template/npm-install.bat +4 -0
  251. package/template/npm-install.sh +5 -0
  252. package/template/readme.md +31 -0
  253. package/template/shared/server.crt +15 -0
  254. package/template/shared/server.key +15 -0
  255. package/template/web-server/app.js +25 -0
  256. package/template/web-server/app.js.https +36 -0
  257. package/template/web-server/bin/component.bat +1 -0
  258. package/template/web-server/bin/component.sh +1 -0
  259. package/template/web-server/package.json +10 -0
  260. package/template/web-server/public/css/base.css +76 -0
  261. package/template/web-server/public/image/logo.png +0 -0
  262. package/template/web-server/public/image/sp.png +0 -0
  263. package/template/web-server/public/index.html +57 -0
  264. package/template/web-server/public/index.html.sio +58 -0
  265. package/template/web-server/public/js/lib/build/build.js +1730 -0
  266. package/template/web-server/public/js/lib/build/build.js.wss +1721 -0
  267. package/template/web-server/public/js/lib/component.json +6 -0
  268. package/template/web-server/public/js/lib/local/boot/component.json +11 -0
  269. package/template/web-server/public/js/lib/local/boot/index.js +11 -0
  270. package/template/web-server/public/js/lib/meloclient.js +456 -0
  271. package/template/web-server/public/js/lib/meloclient.js.wss +456 -0
  272. package/template/web-server/public/js/lib/socket.io.js +3 -0
  273. package/test/application.ts +607 -0
  274. package/test/filters/handler/serial.ts +47 -0
  275. package/test/filters/handler/time.ts +47 -0
  276. package/test/filters/handler/timeout.ts +46 -0
  277. package/test/filters/handler/toobusy.ts +59 -0
  278. package/test/filters/rpc/rpcLog.ts +20 -0
  279. package/test/filters/rpc/toobusy.ts +40 -0
  280. package/test/manager/mockChannelManager.ts +92 -0
  281. package/test/manager/taskManager.ts +78 -0
  282. package/test/mock-base/app/servers/other-file +0 -0
  283. package/test/mock-plugin/components/mockPlugin.ts +8 -0
  284. package/test/mock-plugin/events/mockEvent.ts +12 -0
  285. package/test/modules/console.ts +264 -0
  286. package/test/pomelo.ts +18 -0
  287. package/test/remote/channelRemote.ts +176 -0
  288. package/test/service/channel.ts +161 -0
  289. package/test/service/channelService.ts +243 -0
  290. package/test/service/connectionService.ts +142 -0
  291. package/test/service/filterService.ts +165 -0
  292. package/test/service/handlerService.ts +77 -0
  293. package/test/service/sessionService.ts +464 -0
  294. package/test/util/countDownLatch.ts +81 -0
  295. package/test/util/pathUtil.ts +122 -0
  296. package/test/util/utils.ts +165 -0
@@ -0,0 +1,313 @@
1
+ import * as async from 'async';
2
+ import * as log from './log';
3
+ import * as utils from './utils';
4
+ import * as path from 'path';
5
+ import * as fs from 'fs';
6
+ import * as Constants from './constants';
7
+ import * as starter from '../master/starter';
8
+ import * as Loader from '@bigtyphoon/melo-loader';
9
+ import { getLogger } from '@bigtyphoon/melo-logger'; import { Application } from '../application';
10
+ import { melo } from '../melo';
11
+ import { ServerInfo } from './constants';
12
+ import { IComponent, ILifeCycle } from '../index';
13
+ let logger = getLogger('melo', path.basename(__filename));
14
+
15
+
16
+ /**
17
+ * Initialize application configuration.
18
+ */
19
+ export function defaultConfiguration(app: Application) {
20
+ let args = parseArgs(process.argv);
21
+ setupEnv(app, args);
22
+ loadMaster(app);
23
+ loadServers(app);
24
+ processArgs(app, args);
25
+ configLogger(app);
26
+ loadLifecycle(app);
27
+ }
28
+
29
+ /**
30
+ * Start servers by type.
31
+ */
32
+ export function startByType(app: Application, cb: (err?: Error) => void) {
33
+ if (!!app.startId) {
34
+ if (app.startId === Constants.RESERVED.MASTER) {
35
+ utils.invokeCallback(cb);
36
+ } else {
37
+ starter.runServers(app);
38
+ }
39
+ } else {
40
+ if (!!app.type && app.type !== Constants.RESERVED.ALL && app.type !== Constants.RESERVED.MASTER) {
41
+ starter.runServers(app);
42
+ } else {
43
+ utils.invokeCallback(cb);
44
+ }
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Load default components for application.
50
+ */
51
+ export function loadDefaultComponents(app: Application) {
52
+ // load system default components
53
+ if (app.serverType === Constants.RESERVED.MASTER) {
54
+ app.load(melo.components.master, app.get('masterConfig'));
55
+ } else {
56
+ app.load(melo.components.proxy, app.get('proxyConfig'));
57
+ if (app.getCurServer().port) {
58
+ app.load(melo.components.remote, app.get('remoteConfig'));
59
+ }
60
+ if (app.isFrontend()) {
61
+ app.load(melo.components.connection, app.get('connectionConfig'));
62
+ app.load(melo.components.connector, app.get('connectorConfig'));
63
+ app.load(melo.components.session, app.get('sessionConfig'));
64
+ // compatible for schedulerConfig
65
+ if (app.get('schedulerConfig')) {
66
+ app.load(melo.components.pushScheduler, app.get('schedulerConfig'));
67
+ } else {
68
+ app.load(melo.components.pushScheduler, app.get('pushSchedulerConfig'));
69
+ }
70
+ }
71
+ app.load(melo.components.backendSession, app.get('backendSessionConfig'));
72
+ app.load(melo.components.channel, app.get('channelConfig'));
73
+ app.load(melo.components.server, app.get('serverConfig'));
74
+ }
75
+ app.load(melo.components.monitor, app.get('monitorConfig'));
76
+ }
77
+
78
+ /**
79
+ * Stop components.
80
+ *
81
+ * @param {Array} comps component list
82
+ * @param {Number} index current component index
83
+ * @param {Boolean} force whether stop component immediately
84
+ * @param {Function} cb
85
+ */
86
+ export function stopComps(comps: IComponent[], index: number, force: boolean, cb: () => void ) {
87
+ if (index >= comps.length) {
88
+ utils.invokeCallback(cb);
89
+ return;
90
+ }
91
+ let comp = comps[index];
92
+ if (typeof comp.stop === 'function') {
93
+ comp.stop(force, function () {
94
+ // ignore any error
95
+ stopComps(comps, index + 1, force, cb);
96
+ });
97
+ } else {
98
+ stopComps(comps, index + 1, force, cb);
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Apply command to loaded components.
104
+ * This method would invoke the component {method} in series.
105
+ * Any component {method} return err, it would return err directly.
106
+ *
107
+ * @param {Array} comps loaded component list
108
+ * @param {String} method component lifecycle method name, such as: start, stop
109
+ * @param {Function} cb
110
+ */
111
+ export function optComponents(comps: IComponent[], method: string, cb: (err?: Error) => void) {
112
+ let i = 0;
113
+ async.forEachSeries(comps, function (comp, done) {
114
+ i++;
115
+ if (typeof (comp as any)[method] === 'function') {
116
+ (comp as any)[method](done);
117
+ } else {
118
+ done();
119
+ }
120
+ }, function (err: Error) {
121
+ if (err) {
122
+ if (typeof err === 'string') {
123
+ logger.error('fail to operate component, method: %s, err: %j', method, err);
124
+ } else {
125
+ logger.error('fail to operate component, method: %s, err: %j', method, err.stack);
126
+ }
127
+ }
128
+ utils.invokeCallback(cb, err);
129
+ });
130
+ }
131
+
132
+ export function optLifecycles(comps: ILifeCycle[], method: string, app: Application, cb: (err?: Error) => void, arg2 ?: any) {
133
+ let i = 0;
134
+ async.forEachSeries(comps, function (comp, done) {
135
+ i++;
136
+ if (typeof (comp as any)[method] === 'function') {
137
+ (comp as any)[method](app , done , arg2);
138
+ } else {
139
+ done();
140
+ }
141
+ }, function (err: Error) {
142
+ if (err) {
143
+ if (typeof err === 'string') {
144
+ logger.error('fail to operate lifecycle, method: %s, err: %j', method, err);
145
+ } else {
146
+ logger.error('fail to operate lifecycle, method: %s, err: %j', method, err.stack);
147
+ }
148
+ }
149
+ utils.invokeCallback(cb, err);
150
+ });
151
+ }
152
+
153
+
154
+ /**
155
+ * Load server info from config/servers.json.
156
+ */
157
+ let loadServers = function (app: Application) {
158
+ app.loadConfigBaseApp(Constants.RESERVED.SERVERS, Constants.FILEPATH.SERVER);
159
+ let servers = app.get(Constants.RESERVED.SERVERS);
160
+ let serverMap: {[serverId: string]: ServerInfo} = {}, slist, i, l, server;
161
+ for (let serverType in servers) {
162
+ slist = servers[serverType];
163
+ for (i = 0, l = slist.length; i < l; i++) {
164
+ server = slist[i];
165
+ server.serverType = serverType;
166
+ if (server[Constants.RESERVED.CLUSTER_COUNT]) {
167
+ utils.loadCluster(app, server, serverMap);
168
+ continue;
169
+ }
170
+ serverMap[server.id] = server;
171
+ if (server.wsPort) {
172
+ logger.warn('wsPort is deprecated, use clientPort in frontend server instead, server: %j', server);
173
+ }
174
+ }
175
+ }
176
+ app.set(Constants.KEYWORDS.SERVER_MAP, serverMap);
177
+ };
178
+
179
+ /**
180
+ * Load master info from config/master.json.
181
+ */
182
+ let loadMaster = function (app: Application) {
183
+ app.loadConfigBaseApp(Constants.RESERVED.MASTER, Constants.FILEPATH.MASTER);
184
+ app.master = app.get(Constants.RESERVED.MASTER);
185
+ };
186
+
187
+ export interface ServerStartArgs extends ServerInfo {
188
+ mode?: Constants.RESERVED.CLUSTER | Constants.RESERVED.STAND_ALONE;
189
+ masterha ?: 'true' | 'false';
190
+ type ?: Constants.RESERVED.ALL;
191
+ startId ?: string;
192
+ main ?: string;
193
+ }
194
+
195
+ /**
196
+ * Process server start command
197
+ */
198
+ let processArgs = function (app: Application, args: ServerStartArgs) {
199
+ let serverType = args.serverType || Constants.RESERVED.MASTER;
200
+ let serverId = args.id || app.getMaster().id;
201
+ let mode = args.mode || Constants.RESERVED.CLUSTER;
202
+ let masterha = args.masterha || 'false';
203
+ let type = args.type || Constants.RESERVED.ALL;
204
+ let startId = args.startId;
205
+
206
+ app.set(Constants.RESERVED.MAIN, args.main, true);
207
+ app.set(Constants.RESERVED.SERVER_TYPE, serverType, true);
208
+ app.set(Constants.RESERVED.SERVER_ID, serverId, true);
209
+ app.set(Constants.RESERVED.MODE, mode, true);
210
+ app.set(Constants.RESERVED.TYPE, type, true);
211
+ if (!!startId) {
212
+ app.set(Constants.RESERVED.STARTID, startId, true);
213
+ }
214
+
215
+ if (masterha === 'true') {
216
+ app.master = args;
217
+ app.set(Constants.RESERVED.CURRENT_SERVER, args, true);
218
+ } else if (serverType !== Constants.RESERVED.MASTER) {
219
+ app.set(Constants.RESERVED.CURRENT_SERVER, args, true);
220
+ } else {
221
+ app.set(Constants.RESERVED.CURRENT_SERVER, app.getMaster(), true);
222
+ }
223
+ };
224
+
225
+ /**
226
+ * Setup enviroment.
227
+ */
228
+ let setupEnv = function (app: Application, args: {env: string}) {
229
+ app.set(Constants.RESERVED.ENV, args.env || process.env.NODE_ENV || Constants.RESERVED.ENV_DEV, true);
230
+ };
231
+ let _checkCanRequire = (path: string) => {
232
+ try {
233
+ path = require.resolve(path);
234
+ } catch(err) {
235
+ return null;
236
+ }
237
+ return path;
238
+ };
239
+
240
+ /**
241
+ * Configure custom logger.
242
+ */
243
+ let configLogger = function (app: Application) {
244
+ if (process.env.POMELO_LOGGER !== 'off') {
245
+ let env = app.get(Constants.RESERVED.ENV);
246
+ let originPath = path.join(app.getBase(), Constants.FILEPATH.LOG);
247
+ let presentPath = path.join(app.getBase(), Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.LOG));
248
+
249
+ if (_checkCanRequire(originPath)) {
250
+ log.configure(app, originPath);
251
+ } else if (_checkCanRequire(presentPath)) {
252
+ log.configure(app, presentPath);
253
+ } else {
254
+ logger.error('logger file path configuration is error.');
255
+ }
256
+ }
257
+ };
258
+
259
+ /**
260
+ * Parse command line arguments.
261
+ *
262
+ * @param args command line arguments
263
+ *
264
+ * @return Object argsMap map of arguments
265
+ */
266
+ let parseArgs = function (args: string[]) {
267
+ let argsMap: any = {};
268
+ let mainPos = 1;
269
+
270
+ while (args[mainPos].indexOf('--') > 0) {
271
+ mainPos++;
272
+ }
273
+ argsMap.main = args[mainPos];
274
+
275
+ for (let i = (mainPos + 1); i < args.length; i++) {
276
+ let arg = args[i];
277
+ let sep = arg.indexOf('=');
278
+ let key = arg.slice(0, sep);
279
+ let value = arg.slice(sep + 1);
280
+ if (!isNaN(Number(value)) && (value.indexOf('.') < 0)) {
281
+ value = Number(value) as any;
282
+ }
283
+ argsMap[key] = value;
284
+ }
285
+
286
+ return argsMap;
287
+ };
288
+
289
+ /**
290
+ * Load lifecycle file.
291
+ *
292
+ */
293
+ let loadLifecycle = function (app: Application) {
294
+ let filePath = path.join(app.getBase(), Constants.FILEPATH.SERVER_DIR, app.serverType, Constants.FILEPATH.LIFECYCLE);
295
+ try {
296
+ filePath = require.resolve(filePath);
297
+ } catch(err) {
298
+ return;
299
+ }
300
+
301
+ let lifecycle = require(filePath);
302
+ if (!filePath) {
303
+ logger.error('lifecycle.js in %s is error format.', filePath);
304
+ return;
305
+ }
306
+ if (typeof lifecycle.default === 'function') {
307
+ lifecycle = lifecycle.default(app);
308
+ } else {
309
+ logger.error('lifecycle.js in %s is error format.', filePath);
310
+ return;
311
+ }
312
+ app.usedPlugins.push(lifecycle);
313
+ };
@@ -0,0 +1,154 @@
1
+ import { RemoteServerCode } from '../index';
2
+
3
+
4
+ export enum KEYWORDS {
5
+ BEFORE_FILTER= '__befores__',
6
+ AFTER_FILTER= '__afters__',
7
+ GLOBAL_BEFORE_FILTER= '__globalBefores__',
8
+ GLOBAL_AFTER_FILTER= '__globalAfters__',
9
+ ROUTE= '__routes__',
10
+ BEFORE_STOP_HOOK= '__beforeStopHook__',
11
+ MODULE= '__modules__',
12
+ SERVER_MAP= '__serverMap__',
13
+ RPC_BEFORE_FILTER= '__rpcBefores__',
14
+ RPC_AFTER_FILTER= '__rpcAfters__',
15
+ MASTER_WATCHER= '__masterwatcher__',
16
+ MONITOR_WATCHER= '__monitorwatcher__'
17
+ }
18
+
19
+ export enum FILEPATH {
20
+ MASTER = '/config/master.json',
21
+ SERVER = '/config/servers.json',
22
+ CRON = '/config/crons.json',
23
+ LOG = '/config/log4js.json',
24
+ SERVER_PROTOS = '/config/serverProtos.json',
25
+ CLIENT_PROTOS = '/config/clientProtos.json',
26
+ MASTER_HA = '/config/masterha.json',
27
+ LIFECYCLE = '/lifecycle.js',
28
+ SERVER_DIR = '/app/servers/',
29
+ CONFIG_DIR = '/config'
30
+ }
31
+
32
+ export enum DIR {
33
+ HANDLER = 'handler',
34
+ REMOTE = 'remote',
35
+ CRON = 'cron',
36
+ LOG = 'logs',
37
+ SCRIPT = 'scripts',
38
+ EVENT = 'events',
39
+ COMPONENT = 'components'
40
+ }
41
+
42
+ export enum RESERVED {
43
+ BASE = 'base',
44
+ MAIN = 'main',
45
+ MASTER = 'master',
46
+ SERVERS = 'servers',
47
+ ENV = 'env',
48
+ CPU = 'cpu',
49
+ ENV_DEV = 'development',
50
+ ENV_PRO = 'production',
51
+ ALL = 'all',
52
+ SERVER_TYPE = 'serverType',
53
+ SERVER_ID = 'serverId',
54
+ CURRENT_SERVER = 'curServer',
55
+ MODE = 'mode',
56
+ TYPE = 'type',
57
+ CLUSTER = 'clusters',
58
+ STAND_ALONE = 'stand-alone',
59
+ BEFORE_START = 'beforeStart',
60
+ START = 'start',
61
+ AFTER_START = 'afterStart',
62
+ AFTER_STARTALL = 'afterStartAll',
63
+ CRONS = 'crons',
64
+ ERROR_HANDLER = 'errorHandler',
65
+ GLOBAL_ERROR_HANDLER = 'globalErrorHandler',
66
+ AUTO_RESTART = 'auto-restart',
67
+ RESTART_FORCE = 'restart-force',
68
+ CLUSTER_COUNT = 'clusterCount',
69
+ CLUSTER_PREFIX = 'cluster-server-',
70
+ CLUSTER_SIGNAL = '++',
71
+ RPC_ERROR_HANDLER = 'rpcErrorHandler',
72
+ SERVER = 'server',
73
+ CLIENT = 'client',
74
+ STARTID = 'startId',
75
+ STOP_SERVERS = 'stop_servers',
76
+ SSH_CONFIG_PARAMS = 'ssh_config_params'
77
+ }
78
+
79
+ export enum COMMAND {
80
+ TASKSET = 'taskset',
81
+ KILL = 'kill',
82
+ TASKKILL = 'taskkill',
83
+ SSH = 'ssh'
84
+ }
85
+
86
+ export enum PLATFORM {
87
+ WIN = 'win32',
88
+ LINUX = 'linux'
89
+ }
90
+
91
+ export enum LIFECYCLE {
92
+ BEFORE_STARTUP = 'beforeStartup',
93
+ BEFORE_SHUTDOWN = 'beforeShutdown',
94
+ AFTER_STARTUP = 'afterStartup',
95
+ AFTER_STARTALL = 'afterStartAll'
96
+ }
97
+
98
+ export enum SIGNAL {
99
+ FAIL = 0,
100
+ OK = 1
101
+ }
102
+
103
+ export enum TIME {
104
+ TIME_WAIT_STOP = 3 * 1000,
105
+ TIME_WAIT_KILL = 5 * 1000,
106
+ TIME_WAIT_RESTART = 5 * 1000,
107
+ TIME_WAIT_COUNTDOWN = 10 * 1000,
108
+ TIME_WAIT_MASTER_KILL = 2 * 60 * 1000,
109
+ TIME_WAIT_MONITOR_KILL = 2 * 1000,
110
+ TIME_WAIT_PING = 30 * 1000,
111
+ TIME_WAIT_MAX_PING = 5 * 60 * 1000,
112
+ DEFAULT_UDP_HEARTBEAT_TIME = 20 * 1000,
113
+ DEFAULT_UDP_HEARTBEAT_TIMEOUT = 100 * 1000,
114
+ DEFAULT_MQTT_HEARTBEAT_TIMEOUT = 90 * 1000
115
+ }
116
+
117
+ export interface RouteRecord {
118
+ route: string;
119
+ serverType: string;
120
+ handler: string;
121
+ method: string;
122
+ }
123
+
124
+ export type UID = string;
125
+ export type SID = number;
126
+ export type FRONTENDID = string;
127
+
128
+ /**
129
+ * ServerInfo
130
+ */
131
+ export interface ServerInfo {
132
+ id: string;
133
+ serverType: string;
134
+ host: string;
135
+ port: number;
136
+ clientHost?: string;
137
+ clientPort?: number;
138
+ frontend ?: boolean;
139
+
140
+ args ?: string | string[];
141
+ cpu ?: number;
142
+
143
+ ['max-connections'] ?: number;
144
+ ['auto-restart'] ?: boolean;
145
+ ['restart-force'] ?: boolean;
146
+ ['clusterCount'] ?: number;
147
+
148
+ handlerPaths ?: string[];
149
+ remoterPaths ?: RemoteServerCode[];
150
+ // 进程id number
151
+ pid?: any;
152
+ // 进程启动时的 env 参数
153
+ env?: string;
154
+ }
@@ -0,0 +1,72 @@
1
+
2
+ export interface CountDownLatchOptions {
3
+ timeout ?: number;
4
+ }
5
+
6
+ export type CountDownLatchCallback = (isTimeout ?: boolean) => void;
7
+
8
+ /**
9
+ * Count down to zero or timeout and invoke cb finally.
10
+ */
11
+ export class CountDownLatch {
12
+ count: number;
13
+ cb: CountDownLatchCallback;
14
+ timerId: any;
15
+ constructor(count: number, opts: CountDownLatchOptions, cb: CountDownLatchCallback) {
16
+ this.count = count;
17
+ this.cb = cb;
18
+ let self = this;
19
+ if (opts.timeout) {
20
+ this.timerId = setTimeout(function () {
21
+ self.cb(true);
22
+ }, opts.timeout);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Call when a task finish to count down.
28
+ *
29
+ * @api public
30
+ */
31
+ done() {
32
+ if (this.count <= 0) {
33
+ throw new Error('illegal state.');
34
+ }
35
+
36
+ this.count--;
37
+ if (this.count === 0) {
38
+ if (this.timerId) {
39
+ clearTimeout(this.timerId);
40
+ }
41
+ this.cb();
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Create a count down latch
48
+ *
49
+ * @param {Integer} count
50
+ * @param {Object} opts, opts.timeout indicates timeout, optional param
51
+ * @param {Function} cb, cb(isTimeout)
52
+ *
53
+ * @api public
54
+ */
55
+ export function createCountDownLatch(count: number, cb ?: CountDownLatchCallback): CountDownLatch;
56
+ export function createCountDownLatch(count: number, opts: CountDownLatchOptions, cb ?: CountDownLatchCallback): CountDownLatch;
57
+ export function createCountDownLatch(count: number, opts ?: CountDownLatchCallback | CountDownLatchOptions, cb ?: CountDownLatchCallback) {
58
+ if(!count || count <= 0) {
59
+ throw new Error('count should be positive.');
60
+ }
61
+
62
+ if (!cb && typeof opts === 'function') {
63
+ cb = opts;
64
+ opts = {};
65
+ }
66
+
67
+ if(typeof cb !== 'function') {
68
+ throw new Error('cb should be a function.');
69
+ }
70
+
71
+ return new CountDownLatch(count, opts as CountDownLatchOptions, cb);
72
+ }
@@ -0,0 +1,15 @@
1
+ export enum AppEvents {
2
+ ADD_SERVERS= 'add_servers',
3
+ REMOVE_SERVERS= 'remove_servers',
4
+ REPLACE_SERVERS= 'replace_servers',
5
+ BIND_SESSION= 'bind_session',
6
+ UNBIND_SESSION= 'unbind_session',
7
+ CLOSE_SESSION= 'close_session',
8
+ ADD_CRONS= 'add_crons',
9
+ REMOVE_CRONS= 'remove_crons',
10
+ START_SERVER= 'start_server',
11
+ START_ALL= 'start_all',
12
+ // ProtobufComponent 组件,当协议文件热更新时 通知 参数: type(server|client)
13
+ PROTO_CHANGED= 'proto_changed',
14
+ }
15
+ export default AppEvents;
@@ -0,0 +1,5 @@
1
+ import { FrontendOrBackendSession } from '../server/server';
2
+
3
+ export function bindHandlerMethod<T, MSG, R, F>(method: ((msg: MSG, session: FrontendOrBackendSession) => Promise<R>), thisArg: T): (msg: MSG) => Promise<R> {
4
+ return method.bind(thisArg) as any;
5
+ }
@@ -0,0 +1,11 @@
1
+ import * as logger from '@bigtyphoon/melo-logger';
2
+ import { Application } from '../application';
3
+
4
+ /**
5
+ * Configure melo logger
6
+ */
7
+ export function configure(app: Application, filename: string) {
8
+ let serverId = app.getServerId();
9
+ let base = app.getBase();
10
+ logger.configure(filename, {serverId: serverId, base: base});
11
+ }
@@ -0,0 +1,110 @@
1
+ import * as os from 'os';
2
+ import * as admin from '@bigtyphoon/melo-admin';
3
+ import * as utils from './utils';
4
+ import * as Constants from './constants';
5
+ import * as pathUtil from './pathUtil';
6
+ import * as starter from '../master/starter';
7
+ import { getLogger } from '@bigtyphoon/melo-logger'; import { Application } from '../application';
8
+ import { ConsoleService, IModule, IModuleFactory } from '@bigtyphoon/melo-admin';
9
+ import { MasterWatcherModule } from '../modules/masterwatcher';
10
+ import { MonitorWatcherModule } from '../modules/monitorwatcher';
11
+ import { WatchServerModule } from '../modules/watchServer';
12
+ import { OnlineUserModule } from '../modules/onlineUser';
13
+ import { ConsoleModule } from '../modules/console';
14
+ import * as path from 'path';
15
+ let logger = getLogger('melo', path.basename(__filename));
16
+
17
+
18
+ export interface ModuleRecord {
19
+ module: IModuleFactory | IModule;
20
+ moduleId: string;
21
+ opts: any;
22
+ }
23
+ /**
24
+ * Load admin modules
25
+ */
26
+ export function loadModules(self: {app: Application , modules: Array<IModule>}, consoleService: ConsoleService) {
27
+ // load app register modules
28
+ let _modules = self.app.get(Constants.KEYWORDS.MODULE);
29
+
30
+ if (!_modules) {
31
+ return;
32
+ }
33
+
34
+ let modules = [];
35
+ for (let m in _modules) {
36
+ modules.push(_modules[m]);
37
+ }
38
+
39
+ let record, moduleId, module;
40
+ for (let i = 0, l = modules.length; i < l; i++) {
41
+ record = modules[i];
42
+ if (typeof record.module === 'function') {
43
+ module = new record.module(record.opts, consoleService);
44
+ } else {
45
+ module = record.module;
46
+ }
47
+
48
+ moduleId = record.moduleId || module.moduleId;
49
+
50
+ if (!moduleId) {
51
+ logger.warn('ignore an unknown module.');
52
+ continue;
53
+ }
54
+
55
+ consoleService.register(moduleId, module);
56
+ self.modules.push(module);
57
+ }
58
+ }
59
+
60
+ export function startModules(modules: IModule[], cb: (err?: Error) => void) {
61
+ // invoke the start lifecycle method of modules
62
+
63
+ if (!modules) {
64
+ return;
65
+ }
66
+ startModule(null, modules, 0, cb);
67
+ }
68
+
69
+ /**
70
+ * Append the default system admin modules
71
+ */
72
+ export function registerDefaultModules(isMaster: boolean, app: Application, closeWatcher: boolean) {
73
+ if (!closeWatcher) {
74
+ if (isMaster) {
75
+ app.registerAdmin(MasterWatcherModule, { app: app });
76
+ } else {
77
+ app.registerAdmin(MonitorWatcherModule, { app: app });
78
+ }
79
+ }
80
+ app.registerAdmin(WatchServerModule, { app: app });
81
+ app.registerAdmin(ConsoleModule, { app: app, starter: starter });
82
+ if (app.enabled('systemMonitor')) {
83
+ if (os.platform() !== Constants.PLATFORM.WIN) {
84
+ app.registerAdmin(admin.modules.systemInfo);
85
+ app.registerAdmin(admin.modules.nodeInfo);
86
+ }
87
+ app.registerAdmin(OnlineUserModule);
88
+ app.registerAdmin(admin.modules.monitorLog, { path: pathUtil.getLogPath(app.getBase()) });
89
+ app.registerAdmin(admin.modules.scripts, { app: app, path: pathUtil.getScriptPath(app.getBase()) });
90
+ if (os.platform() !== Constants.PLATFORM.WIN) {
91
+ app.registerAdmin(admin.modules.profiler);
92
+ }
93
+ }
94
+ }
95
+
96
+ let startModule = function (err: Error, modules: IModule[], index: number, cb: (err?: Error) => void) {
97
+ if (err || index >= modules.length) {
98
+ utils.invokeCallback(cb, err);
99
+ return;
100
+ }
101
+
102
+ let module = modules[index];
103
+ if (module && typeof module.start === 'function') {
104
+ module.start((err) => {
105
+ startModule(err, modules, index + 1, cb);
106
+ });
107
+ } else {
108
+ startModule(err, modules, index + 1, cb);
109
+ }
110
+ };