typespeed 2.3.6 → 2.4.1
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.
- package/app/src/config-development.json +3 -2
- package/app/src/test-socket.class.ts +56 -0
- package/app/src/views/socket.html +23 -0
- package/dist/default/express-server.class.js +20 -5
- package/dist/default/rabbitmq.class.js +3 -3
- package/dist/default/redis.class.js +1 -1
- package/dist/default/socket-io.class.js +64 -0
- package/dist/typespeed.d.ts +19 -1
- package/dist/typespeed.js +6 -3
- package/package.json +7 -5
- package/src/default/express-server.class.ts +18 -7
- package/src/default/rabbitmq.class.ts +3 -3
- package/src/default/redis.class.ts +1 -1
- package/src/default/socket-io.class.ts +68 -0
- package/src/factory/server-factory.class.ts +1 -1
- package/src/typespeed.d.ts +19 -1
- package/src/typespeed.ts +7 -4
- package/test/socket.test.ts +60 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SocketIo, getMapping, component, io } from "../../src/typespeed";
|
|
2
|
+
|
|
3
|
+
@component
|
|
4
|
+
export default class TestSocket {
|
|
5
|
+
|
|
6
|
+
static names = ["LiLei", "HanMeiMei"];
|
|
7
|
+
|
|
8
|
+
static loginUsers: Map<string, string> = new Map<string, string>();
|
|
9
|
+
|
|
10
|
+
@SocketIo.onConnected
|
|
11
|
+
public connected(socket, next) {
|
|
12
|
+
// 从 names 里面取出一个名字
|
|
13
|
+
let name = TestSocket.names.pop();
|
|
14
|
+
TestSocket.loginUsers.set(socket.id, name);
|
|
15
|
+
//io.sockets.emit("all", "We have a new member: " + name);
|
|
16
|
+
//console.log(socket.handshake);
|
|
17
|
+
//console.log(socket.id);
|
|
18
|
+
//next(new Error("test-error"));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@SocketIo.onDisconnect
|
|
22
|
+
public disconnet(socket, reason) {
|
|
23
|
+
io.sockets.emit("all", "We lost a member by: " + reason);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@SocketIo.onEvent("test-error")
|
|
27
|
+
public testError(socket, message) {
|
|
28
|
+
throw new Error("test-error");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@SocketIo.onError
|
|
32
|
+
public error(socket, err) {
|
|
33
|
+
io.sockets.emit("all", "We have a problem!");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@SocketIo.onEvent("say")
|
|
37
|
+
public say(socket, message) {
|
|
38
|
+
io.sockets.emit("all", TestSocket.loginUsers.get(socket.id) + " said: " + message);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@SocketIo.onEvent("join")
|
|
42
|
+
public join(socket, message) {
|
|
43
|
+
socket.join("private-room");
|
|
44
|
+
io.to("private-room").emit("all", TestSocket.loginUsers.get(socket.id) + " joined private-room");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@SocketIo.onEvent("say-inroom")
|
|
48
|
+
public sayInRoom(socket, message) {
|
|
49
|
+
io.to("private-room").emit("all", TestSocket.loginUsers.get(socket.id) + " said in Room: " + message);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@getMapping("/socketIo")
|
|
53
|
+
public socketIoPage(req, res) {
|
|
54
|
+
res.render("socket");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
|
|
3
|
+
<head>
|
|
4
|
+
<title>Socket Test</title>
|
|
5
|
+
<script src="https://cdn.socket.io/4.7.1/socket.io.min.js"></script>
|
|
6
|
+
<script>
|
|
7
|
+
var socket = io('http://localhost:8081');
|
|
8
|
+
socket.on('connect', function() {
|
|
9
|
+
console.log('connected');
|
|
10
|
+
});
|
|
11
|
+
socket.on('all', function(data) {
|
|
12
|
+
console.log(data);
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<button onclick="socket.emit('say', 'I say some thing')">TestSay</button>
|
|
18
|
+
<button onclick="socket.emit('join', 'I want to join the room')">Join</button>
|
|
19
|
+
<button onclick="socket.emit('say-inroom', 'say some in room')">InRoom</button>
|
|
20
|
+
<button onclick="socket.emit('test-error', 'this is a error')">Test Error</button>
|
|
21
|
+
<button onclick="socket.close()">Close</button>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -19,6 +19,7 @@ const expressSession = require("express-session");
|
|
|
19
19
|
const connectRedis = require("connect-redis");
|
|
20
20
|
const server_factory_class_1 = require("../factory/server-factory.class");
|
|
21
21
|
const route_decorator_1 = require("../route.decorator");
|
|
22
|
+
const socket_io_class_1 = require("../default/socket-io.class");
|
|
22
23
|
const typespeed_1 = require("../typespeed");
|
|
23
24
|
const core_decorator_1 = require("../core.decorator");
|
|
24
25
|
const redis_class_1 = require("./redis.class");
|
|
@@ -32,12 +33,18 @@ class ExpressServer extends server_factory_class_1.default {
|
|
|
32
33
|
setMiddleware(middleware) {
|
|
33
34
|
this.middlewareList.push(middleware);
|
|
34
35
|
}
|
|
35
|
-
start(port
|
|
36
|
+
start(port) {
|
|
36
37
|
this.middlewareList.forEach(middleware => {
|
|
37
38
|
this.app.use(middleware);
|
|
38
39
|
});
|
|
39
40
|
this.setDefaultMiddleware();
|
|
40
|
-
|
|
41
|
+
if (this.socketIoConfig) {
|
|
42
|
+
const newSocketApp = socket_io_class_1.SocketIo.setIoServer(this.app, this.socketIoConfig);
|
|
43
|
+
return newSocketApp.listen(port);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return this.app.listen(port);
|
|
47
|
+
}
|
|
41
48
|
}
|
|
42
49
|
setDefaultMiddleware() {
|
|
43
50
|
this.app.use(express.urlencoded({ extended: true }));
|
|
@@ -46,7 +53,7 @@ class ExpressServer extends server_factory_class_1.default {
|
|
|
46
53
|
const viewConfig = this.view;
|
|
47
54
|
this.app.engine(viewConfig["suffix"], consolidate[viewConfig["engine"]]);
|
|
48
55
|
this.app.set('view engine', viewConfig["suffix"]);
|
|
49
|
-
this.app.set('views',
|
|
56
|
+
this.app.set('views', this.mainPath + viewConfig["path"]);
|
|
50
57
|
}
|
|
51
58
|
if (this.session) {
|
|
52
59
|
const sessionConfig = this.session;
|
|
@@ -60,7 +67,7 @@ class ExpressServer extends server_factory_class_1.default {
|
|
|
60
67
|
this.app.use(expressSession(sessionConfig));
|
|
61
68
|
}
|
|
62
69
|
if (this.favicon) {
|
|
63
|
-
const faviconPath =
|
|
70
|
+
const faviconPath = this.mainPath + this.favicon;
|
|
64
71
|
this.app.use(serveFavicon(faviconPath));
|
|
65
72
|
}
|
|
66
73
|
if (this.compression) {
|
|
@@ -71,7 +78,7 @@ class ExpressServer extends server_factory_class_1.default {
|
|
|
71
78
|
}
|
|
72
79
|
this.app.use(this.authentication.preHandle);
|
|
73
80
|
if (this.static) {
|
|
74
|
-
const staticPath =
|
|
81
|
+
const staticPath = this.mainPath + this.static;
|
|
75
82
|
this.app.use(express.static(staticPath));
|
|
76
83
|
}
|
|
77
84
|
(0, route_decorator_1.setRouter)(this.app);
|
|
@@ -136,6 +143,14 @@ __decorate([
|
|
|
136
143
|
(0, typespeed_1.value)("redis"),
|
|
137
144
|
__metadata("design:type", Object)
|
|
138
145
|
], ExpressServer.prototype, "redisConfig", void 0);
|
|
146
|
+
__decorate([
|
|
147
|
+
(0, typespeed_1.value)("socket"),
|
|
148
|
+
__metadata("design:type", Object)
|
|
149
|
+
], ExpressServer.prototype, "socketIoConfig", void 0);
|
|
150
|
+
__decorate([
|
|
151
|
+
(0, typespeed_1.value)("MAIN_PATH"),
|
|
152
|
+
__metadata("design:type", String)
|
|
153
|
+
], ExpressServer.prototype, "mainPath", void 0);
|
|
139
154
|
__decorate([
|
|
140
155
|
core_decorator_1.autoware,
|
|
141
156
|
__metadata("design:type", redis_class_1.Redis)
|
|
@@ -23,13 +23,13 @@ class RabbitMQ {
|
|
|
23
23
|
}
|
|
24
24
|
async publishMessageToExchange(exchange, routingKey, message) {
|
|
25
25
|
const channel = await getChannel();
|
|
26
|
-
await channel.
|
|
26
|
+
await channel.assertExchange(exchange);
|
|
27
27
|
channel.publish(exchange, routingKey, Buffer.from(message));
|
|
28
28
|
await channel.close();
|
|
29
29
|
}
|
|
30
30
|
async sendMessageToQueue(queue, message) {
|
|
31
31
|
const channel = await getChannel();
|
|
32
|
-
await channel.
|
|
32
|
+
await channel.accertQueue(queue);
|
|
33
33
|
channel.sendToQueue(queue, Buffer.from(message));
|
|
34
34
|
await channel.close();
|
|
35
35
|
}
|
|
@@ -61,7 +61,7 @@ function rabbitListener(queue) {
|
|
|
61
61
|
return (target, propertyKey) => {
|
|
62
62
|
(async function () {
|
|
63
63
|
const channel = await getChannel();
|
|
64
|
-
await channel.
|
|
64
|
+
await channel.assertQueue(queue);
|
|
65
65
|
await channel.consume(queue, target[propertyKey], { noAck: true });
|
|
66
66
|
}());
|
|
67
67
|
};
|
|
@@ -14,7 +14,7 @@ const core_decorator_1 = require("../core.decorator");
|
|
|
14
14
|
const ioredis_1 = require("ioredis");
|
|
15
15
|
const typespeed_1 = require("../typespeed");
|
|
16
16
|
const redisSubscribers = {};
|
|
17
|
-
class Redis extends ioredis_1.
|
|
17
|
+
class Redis extends ioredis_1.default {
|
|
18
18
|
getRedis() {
|
|
19
19
|
return Redis.getInstanceOfRedis("pub");
|
|
20
20
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.io = exports.SocketIo = void 0;
|
|
4
|
+
const socket_io_1 = require("socket.io");
|
|
5
|
+
const http_1 = require("http");
|
|
6
|
+
let io = null;
|
|
7
|
+
exports.io = io;
|
|
8
|
+
const listeners = { "event": [], "disconnect": null, "error": null, "connected": null };
|
|
9
|
+
class SocketIo {
|
|
10
|
+
static setIoServer(app, ioSocketConfig) {
|
|
11
|
+
const httpServer = (0, http_1.createServer)(app);
|
|
12
|
+
exports.io = io = new socket_io_1.Server(httpServer, ioSocketConfig);
|
|
13
|
+
io.use((socket, next) => {
|
|
14
|
+
if (listeners["connected"] !== null) {
|
|
15
|
+
listeners["connected"](socket, async (err) => {
|
|
16
|
+
if (listeners["error"] !== null && err) {
|
|
17
|
+
await listeners["error"](socket, err);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
next();
|
|
22
|
+
});
|
|
23
|
+
io.on("connection", (socket) => {
|
|
24
|
+
if (listeners["disconnect"] !== null) {
|
|
25
|
+
socket.on("disconnect", async (reason) => {
|
|
26
|
+
await listeners["disconnect"](socket, reason);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
socket.use(async ([event, ...args], next) => {
|
|
30
|
+
try {
|
|
31
|
+
for (let listener of listeners["event"]) {
|
|
32
|
+
if (listener[1] === event) {
|
|
33
|
+
await listener[0](socket, ...args);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
next(err);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
if (listeners["error"] !== null) {
|
|
42
|
+
socket.on("error", async (err) => {
|
|
43
|
+
await listeners["error"](socket, err);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return httpServer;
|
|
48
|
+
}
|
|
49
|
+
static onEvent(event) {
|
|
50
|
+
return (target, propertyKey) => {
|
|
51
|
+
listeners["event"].push([target[propertyKey], event]);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
static onError(target, propertyKey) {
|
|
55
|
+
listeners["error"] = target[propertyKey];
|
|
56
|
+
}
|
|
57
|
+
static onDisconnect(target, propertyKey) {
|
|
58
|
+
listeners["disconnect"] = target[propertyKey];
|
|
59
|
+
}
|
|
60
|
+
static onConnected(target, propertyKey) {
|
|
61
|
+
listeners["connected"] = target[propertyKey];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.SocketIo = SocketIo;
|
package/dist/typespeed.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as express from "express";
|
|
2
2
|
import { Redis as IoRedis, RedisKey } from "ioredis";
|
|
3
|
+
import { Server as IoServer } from "socket.io";
|
|
3
4
|
import "reflect-metadata";
|
|
4
5
|
|
|
5
6
|
/**设置路由中间件 */
|
|
@@ -375,5 +376,22 @@ declare class ExpressServer extends ServerFactory {
|
|
|
375
376
|
start(port: number): void;
|
|
376
377
|
private setDefaultMiddleware;
|
|
377
378
|
}
|
|
379
|
+
/**Socket IO 装饰器类 */
|
|
380
|
+
declare class SocketIo {
|
|
381
|
+
public static setIoServer(app, ioSocketConfig);
|
|
382
|
+
/**
|
|
383
|
+
* Socket IO 事件装饰器
|
|
384
|
+
* @param event 事件名称
|
|
385
|
+
*/
|
|
386
|
+
public static onEvent(event: string): (target: any, propertyKey: string) => void;
|
|
387
|
+
/**Socket IO 错误捕获装饰器 */
|
|
388
|
+
public static onError(target: any, propertyKey: string): void;
|
|
389
|
+
/**Socket IO 客户端断开连接事件装饰器 */
|
|
390
|
+
public static onDisconnect(target: any, propertyKey: string): void;
|
|
391
|
+
/**Socket IO 客户端连接成功事件装饰器 */
|
|
392
|
+
public static onConnected(target: any, propertyKey: string): void;
|
|
393
|
+
}
|
|
394
|
+
/**Socket IO 服务实现类 */
|
|
395
|
+
declare const io: IoServer;
|
|
378
396
|
|
|
379
|
-
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model };
|
|
397
|
+
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model, SocketIo, io };
|
package/dist/typespeed.js
CHANGED
|
@@ -20,7 +20,7 @@ const fs = require("fs");
|
|
|
20
20
|
const path = require("path");
|
|
21
21
|
const walkSync = require("walk-sync");
|
|
22
22
|
let globalConfig = {};
|
|
23
|
-
const
|
|
23
|
+
const corePath = __dirname;
|
|
24
24
|
const mainPath = path.dirname(getRootPath(new Error().stack.split("\n")) || process.argv[1]);
|
|
25
25
|
const configFile = mainPath + "/config.json";
|
|
26
26
|
if (fs.existsSync(configFile)) {
|
|
@@ -31,15 +31,17 @@ if (fs.existsSync(configFile)) {
|
|
|
31
31
|
globalConfig = Object.assign(globalConfig, JSON.parse(fs.readFileSync(envConfigFile, "utf-8")));
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
globalConfig["MAIN_PATH"] = mainPath;
|
|
35
|
+
globalConfig["CORE_PATH"] = corePath;
|
|
34
36
|
function app(constructor) {
|
|
35
|
-
const coreFiles = walkSync(
|
|
37
|
+
const coreFiles = walkSync(corePath, { globs: ['**/*.ts'], ignore: ['**/*.d.ts', 'scaffold/**'] });
|
|
36
38
|
const mainFiles = walkSync(mainPath, { globs: ['**/*.ts'] });
|
|
37
39
|
(async function () {
|
|
38
40
|
var _a, _b;
|
|
39
41
|
try {
|
|
40
42
|
for (let p of coreFiles) {
|
|
41
43
|
let moduleName = p.replace(".d.ts", "").replace(".ts", "");
|
|
42
|
-
await (_a =
|
|
44
|
+
await (_a = corePath + "/" + moduleName, Promise.resolve().then(() => require(_a)));
|
|
43
45
|
}
|
|
44
46
|
for (let p of mainFiles) {
|
|
45
47
|
let moduleName = p.replace(".d.ts", "").replace(".ts", "");
|
|
@@ -124,3 +126,4 @@ Object.defineProperty(exports, "redisSubscriber", { enumerable: true, get: funct
|
|
|
124
126
|
var read_write_db_class_1 = require("./default/read-write-db.class");
|
|
125
127
|
Object.defineProperty(exports, "ReadWriteDb", { enumerable: true, get: function () { return read_write_db_class_1.default; } });
|
|
126
128
|
__exportStar(require("./default/rabbitmq.class"), exports);
|
|
129
|
+
__exportStar(require("./default/socket-io.class"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typespeed",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "A new Framework for TypeScript.",
|
|
5
5
|
"author": "speedphp",
|
|
6
6
|
"license": "MIT License",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"middleware"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"amqplib": "0.10.3",
|
|
36
37
|
"commander": "^9.4.0",
|
|
37
38
|
"compression": "^1.7.4",
|
|
38
39
|
"connect-redis": "^6.1.3",
|
|
@@ -51,19 +52,20 @@
|
|
|
51
52
|
"node-cache": "^5.1.2",
|
|
52
53
|
"reflect-metadata": "^0.1.13",
|
|
53
54
|
"serve-favicon": "^2.5.0",
|
|
55
|
+
"socket.io": "4.7.1",
|
|
54
56
|
"tracer": "^1.1.6",
|
|
55
|
-
"walk-sync": "^3.0.0"
|
|
56
|
-
"amqplib": "0.10.3"
|
|
57
|
+
"walk-sync": "^3.0.0"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"@types/node": "^18.0.6",
|
|
60
60
|
"@types/express": "^4.17.13",
|
|
61
61
|
"@types/mocha": "^10.0.1",
|
|
62
|
+
"@types/node": "^18.0.6",
|
|
62
63
|
"chai": "4.3.7",
|
|
63
64
|
"chai-http": "^4.4.0",
|
|
64
65
|
"mocha": "10.2.0",
|
|
65
66
|
"nyc": "^15.1.0",
|
|
66
67
|
"ts-node": "^10.9.1",
|
|
67
|
-
"typescript": "^4.9.5"
|
|
68
|
+
"typescript": "^4.9.5",
|
|
69
|
+
"socket.io-client": "4.7.1"
|
|
68
70
|
}
|
|
69
71
|
}
|
|
@@ -8,8 +8,9 @@ import * as expressSession from "express-session";
|
|
|
8
8
|
import * as connectRedis from "connect-redis";
|
|
9
9
|
import ServerFactory from "../factory/server-factory.class";
|
|
10
10
|
import { setRouter } from "../route.decorator";
|
|
11
|
+
import { SocketIo } from "../default/socket-io.class";
|
|
11
12
|
import { value } from "../typespeed";
|
|
12
|
-
import { bean,
|
|
13
|
+
import { bean, error, autoware, resource } from "../core.decorator";
|
|
13
14
|
import { Redis } from "./redis.class";
|
|
14
15
|
import AuthenticationFactory from "../factory/authentication-factory.class";
|
|
15
16
|
|
|
@@ -36,6 +37,12 @@ export default class ExpressServer extends ServerFactory {
|
|
|
36
37
|
@value("redis")
|
|
37
38
|
private redisConfig: object;
|
|
38
39
|
|
|
40
|
+
@value("socket")
|
|
41
|
+
private socketIoConfig: object;
|
|
42
|
+
|
|
43
|
+
@value("MAIN_PATH")
|
|
44
|
+
private mainPath: string;
|
|
45
|
+
|
|
39
46
|
@autoware
|
|
40
47
|
private redisClient: Redis;
|
|
41
48
|
|
|
@@ -53,14 +60,18 @@ export default class ExpressServer extends ServerFactory {
|
|
|
53
60
|
this.middlewareList.push(middleware);
|
|
54
61
|
}
|
|
55
62
|
|
|
56
|
-
public start(port: number
|
|
63
|
+
public start(port: number): any {
|
|
57
64
|
this.middlewareList.forEach(middleware => {
|
|
58
65
|
this.app.use(middleware);
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
this.setDefaultMiddleware();
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
if(this.socketIoConfig) {
|
|
70
|
+
const newSocketApp = SocketIo.setIoServer(this.app, this.socketIoConfig);
|
|
71
|
+
return newSocketApp.listen(port);
|
|
72
|
+
}else{
|
|
73
|
+
return this.app.listen(port);
|
|
74
|
+
}
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
private setDefaultMiddleware() {
|
|
@@ -70,7 +81,7 @@ export default class ExpressServer extends ServerFactory {
|
|
|
70
81
|
const viewConfig = this.view;
|
|
71
82
|
this.app.engine(viewConfig["suffix"], consolidate[viewConfig["engine"]]);
|
|
72
83
|
this.app.set('view engine', viewConfig["suffix"]);
|
|
73
|
-
this.app.set('views',
|
|
84
|
+
this.app.set('views', this.mainPath + viewConfig["path"]);
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
if (this.session) {
|
|
@@ -87,7 +98,7 @@ export default class ExpressServer extends ServerFactory {
|
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
if (this.favicon) {
|
|
90
|
-
const faviconPath =
|
|
101
|
+
const faviconPath = this.mainPath + this.favicon;
|
|
91
102
|
this.app.use(serveFavicon(faviconPath));
|
|
92
103
|
}
|
|
93
104
|
|
|
@@ -102,7 +113,7 @@ export default class ExpressServer extends ServerFactory {
|
|
|
102
113
|
this.app.use(this.authentication.preHandle);
|
|
103
114
|
|
|
104
115
|
if (this.static) {
|
|
105
|
-
const staticPath =
|
|
116
|
+
const staticPath = this.mainPath + this.static;
|
|
106
117
|
this.app.use(express.static(staticPath))
|
|
107
118
|
}
|
|
108
119
|
setRouter(this.app);
|
|
@@ -15,14 +15,14 @@ class RabbitMQ {
|
|
|
15
15
|
|
|
16
16
|
public async publishMessageToExchange(exchange: string, routingKey: string, message: string): Promise<void> {
|
|
17
17
|
const channel = await getChannel();
|
|
18
|
-
await channel.
|
|
18
|
+
await channel.assertExchange(exchange);
|
|
19
19
|
channel.publish(exchange, routingKey, Buffer.from(message));
|
|
20
20
|
await channel.close();
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
public async sendMessageToQueue(queue: string, message: string): Promise<void> {
|
|
24
24
|
const channel = await getChannel();
|
|
25
|
-
await channel.
|
|
25
|
+
await channel.accertQueue(queue);
|
|
26
26
|
channel.sendToQueue(queue, Buffer.from(message));
|
|
27
27
|
await channel.close();
|
|
28
28
|
}
|
|
@@ -51,7 +51,7 @@ function rabbitListener(queue: string) {
|
|
|
51
51
|
return (target: any, propertyKey: string) => {
|
|
52
52
|
(async function () {
|
|
53
53
|
const channel = await getChannel();
|
|
54
|
-
await channel.
|
|
54
|
+
await channel.assertQueue(queue);
|
|
55
55
|
await channel.consume(queue, target[propertyKey], { noAck: true });
|
|
56
56
|
}());
|
|
57
57
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Server as IoServer } from "socket.io";
|
|
2
|
+
import { createServer } from "http";
|
|
3
|
+
|
|
4
|
+
let io: IoServer = null;
|
|
5
|
+
const listeners = { "event": [], "disconnect": null, "error": null, "connected": null };
|
|
6
|
+
|
|
7
|
+
class SocketIo {
|
|
8
|
+
|
|
9
|
+
public static setIoServer(app, ioSocketConfig) {
|
|
10
|
+
const httpServer = createServer(app);
|
|
11
|
+
io = new IoServer(httpServer, ioSocketConfig);
|
|
12
|
+
io.use((socket, next) => {
|
|
13
|
+
if (listeners["connected"] !== null) {
|
|
14
|
+
listeners["connected"](socket, async (err) => {
|
|
15
|
+
if (listeners["error"] !== null && err) {
|
|
16
|
+
await listeners["error"](socket, err);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
next();
|
|
21
|
+
});
|
|
22
|
+
io.on("connection", (socket) => {
|
|
23
|
+
if (listeners["disconnect"] !== null) {
|
|
24
|
+
socket.on("disconnect", async (reason) => {
|
|
25
|
+
await listeners["disconnect"](socket, reason);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
socket.use(async ([event, ...args], next) => {
|
|
29
|
+
try {
|
|
30
|
+
for (let listener of listeners["event"]) {
|
|
31
|
+
if (listener[1] === event) {
|
|
32
|
+
await listener[0](socket, ...args);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch (err) {
|
|
36
|
+
next(err);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (listeners["error"] !== null) {
|
|
41
|
+
socket.on("error", async (err) => {
|
|
42
|
+
await listeners["error"](socket, err);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return httpServer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public static onEvent(event: string) {
|
|
50
|
+
return (target: any, propertyKey: string) => {
|
|
51
|
+
listeners["event"].push([target[propertyKey], event]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public static onError(target: any, propertyKey: string) {
|
|
56
|
+
listeners["error"] = target[propertyKey];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public static onDisconnect(target: any, propertyKey: string) {
|
|
60
|
+
listeners["disconnect"] = target[propertyKey];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public static onConnected(target: any, propertyKey: string) {
|
|
64
|
+
listeners["connected"] = target[propertyKey];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { SocketIo, io }
|
package/src/typespeed.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as express from "express";
|
|
2
2
|
import { Redis as IoRedis, RedisKey } from "ioredis";
|
|
3
|
+
import { Server as IoServer } from "socket.io";
|
|
3
4
|
import "reflect-metadata";
|
|
4
5
|
|
|
5
6
|
/**设置路由中间件 */
|
|
@@ -375,5 +376,22 @@ declare class ExpressServer extends ServerFactory {
|
|
|
375
376
|
start(port: number): void;
|
|
376
377
|
private setDefaultMiddleware;
|
|
377
378
|
}
|
|
379
|
+
/**Socket IO 装饰器类 */
|
|
380
|
+
declare class SocketIo {
|
|
381
|
+
public static setIoServer(app, ioSocketConfig);
|
|
382
|
+
/**
|
|
383
|
+
* Socket IO 事件装饰器
|
|
384
|
+
* @param event 事件名称
|
|
385
|
+
*/
|
|
386
|
+
public static onEvent(event: string): (target: any, propertyKey: string) => void;
|
|
387
|
+
/**Socket IO 错误捕获装饰器 */
|
|
388
|
+
public static onError(target: any, propertyKey: string): void;
|
|
389
|
+
/**Socket IO 客户端断开连接事件装饰器 */
|
|
390
|
+
public static onDisconnect(target: any, propertyKey: string): void;
|
|
391
|
+
/**Socket IO 客户端连接成功事件装饰器 */
|
|
392
|
+
public static onConnected(target: any, propertyKey: string): void;
|
|
393
|
+
}
|
|
394
|
+
/**Socket IO 服务实现类 */
|
|
395
|
+
declare const io: IoServer;
|
|
378
396
|
|
|
379
|
-
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model };
|
|
397
|
+
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model, SocketIo, io };
|
package/src/typespeed.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as path from "path";
|
|
|
4
4
|
import * as walkSync from "walk-sync";
|
|
5
5
|
|
|
6
6
|
let globalConfig = {};
|
|
7
|
-
const
|
|
7
|
+
const corePath = __dirname;
|
|
8
8
|
const mainPath = path.dirname(getRootPath(new Error().stack.split("\n")) || process.argv[1]);
|
|
9
9
|
const configFile = mainPath + "/config.json";
|
|
10
10
|
if (fs.existsSync(configFile)) {
|
|
@@ -15,16 +15,18 @@ if (fs.existsSync(configFile)) {
|
|
|
15
15
|
globalConfig = Object.assign(globalConfig, JSON.parse(fs.readFileSync(envConfigFile, "utf-8")));
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
globalConfig["MAIN_PATH"] = mainPath;
|
|
19
|
+
globalConfig["CORE_PATH"] = corePath;
|
|
18
20
|
|
|
19
21
|
function app<T extends { new(...args: any[]): {} }>(constructor: T) {
|
|
20
|
-
const coreFiles = walkSync(
|
|
22
|
+
const coreFiles = walkSync(corePath, { globs: ['**/*.ts'], ignore: ['**/*.d.ts', 'scaffold/**'] });
|
|
21
23
|
const mainFiles = walkSync(mainPath, { globs: ['**/*.ts'] });
|
|
22
24
|
|
|
23
25
|
(async function () {
|
|
24
26
|
try {
|
|
25
27
|
for (let p of coreFiles) {
|
|
26
28
|
let moduleName = p.replace(".d.ts", "").replace(".ts", "");
|
|
27
|
-
await import(
|
|
29
|
+
await import(corePath + "/" + moduleName);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
for (let p of mainFiles) {
|
|
@@ -99,4 +101,5 @@ export { default as LogDefault} from "./default/log-default.class";
|
|
|
99
101
|
export { default as NodeCache} from "./default/node-cache.class";
|
|
100
102
|
export { Redis, redisSubscriber } from "./default/redis.class";
|
|
101
103
|
export { default as ReadWriteDb} from "./default/read-write-db.class";
|
|
102
|
-
export * from "./default/rabbitmq.class";
|
|
104
|
+
export * from "./default/rabbitmq.class";
|
|
105
|
+
export * from "./default/socket-io.class";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const chaiObj = require('chai');
|
|
2
|
+
chaiObj.use(require("chai-http"));
|
|
3
|
+
import { io as Client } from "socket.io-client";
|
|
4
|
+
const expect = chaiObj.expect;
|
|
5
|
+
|
|
6
|
+
describe("Test Socket IO", () => {
|
|
7
|
+
const testAddr = `http://${process.env.LOCAL_HOST || "localhost"}:8081`;
|
|
8
|
+
let clientHanMeiMei, clientLiLei;
|
|
9
|
+
before((done) => {
|
|
10
|
+
clientHanMeiMei = Client(testAddr);
|
|
11
|
+
clientLiLei = Client(testAddr);
|
|
12
|
+
clientHanMeiMei.on("connect", done);
|
|
13
|
+
});
|
|
14
|
+
after(() => {
|
|
15
|
+
clientHanMeiMei.close();
|
|
16
|
+
clientLiLei.close();
|
|
17
|
+
});
|
|
18
|
+
it("send and receive message", (done) => {
|
|
19
|
+
clientHanMeiMei.on("all", (arg) => {
|
|
20
|
+
expect(arg).to.be.include("LiLei");
|
|
21
|
+
clientHanMeiMei.removeAllListeners("all");
|
|
22
|
+
done();
|
|
23
|
+
});
|
|
24
|
+
clientLiLei.emit("say", "test-from-client-1");
|
|
25
|
+
});
|
|
26
|
+
it("test join room", (done) => {
|
|
27
|
+
clientHanMeiMei.emit("join", "");
|
|
28
|
+
clientHanMeiMei.on("all", (arg) => {
|
|
29
|
+
expect(arg).to.be.include("joined private-room");
|
|
30
|
+
clientHanMeiMei.removeAllListeners("all");
|
|
31
|
+
done();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
it("test say in room", (done) => {
|
|
35
|
+
const message = "I said in Room";
|
|
36
|
+
clientHanMeiMei.on("all", (arg) => {
|
|
37
|
+
expect(arg).to.be.include(message);
|
|
38
|
+
clientHanMeiMei.removeAllListeners("all");
|
|
39
|
+
done();
|
|
40
|
+
});
|
|
41
|
+
clientHanMeiMei.emit("say-inroom", message);
|
|
42
|
+
});
|
|
43
|
+
it("test error catching", (done) => {
|
|
44
|
+
clientHanMeiMei.on("all", (arg) => {
|
|
45
|
+
expect(arg).to.be.include("We have a problem!");
|
|
46
|
+
clientHanMeiMei.removeAllListeners("all");
|
|
47
|
+
done();
|
|
48
|
+
});
|
|
49
|
+
clientHanMeiMei.emit("test-error", "");
|
|
50
|
+
});
|
|
51
|
+
it("test disconnecting", (done) => {
|
|
52
|
+
clientLiLei.on("all", (arg) => {
|
|
53
|
+
expect(arg).to.be.include("lost a member");
|
|
54
|
+
clientLiLei.removeAllListeners("all");
|
|
55
|
+
done();
|
|
56
|
+
});
|
|
57
|
+
clientHanMeiMei.disconnect();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|