-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(intelligence): add websocket service
- Loading branch information
1 parent
00b7536
commit 1996218
Showing
24 changed files
with
1,489 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './websocket'; | ||
export * from './big-number-util'; | ||
export * from './nest-util'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { INestApplication } from '@nestjs/common'; | ||
import { ModuleMetadata } from '@nestjs/common/interfaces'; | ||
import { Test } from '@nestjs/testing'; | ||
|
||
export async function createNestTestApplication(metadata: ModuleMetadata): Promise<INestApplication> { | ||
const testingModule = await Test.createTestingModule(metadata).compile(); | ||
|
||
return testingModule.createNestApplication(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './socketio-rxjs'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import * as http from 'http'; | ||
|
||
import * as express from 'express'; | ||
import * as socketIO from 'socket.io'; | ||
|
||
import { SocketIORxjs } from './socketio-rxjs'; | ||
|
||
describe('SocketIORxjs', () => { | ||
let ioServer: socketIO.Server; | ||
let ioRxjs: SocketIORxjs; | ||
|
||
beforeEach(() => { | ||
const port = 8800; | ||
const app = express(); | ||
const server = http.createServer(app); | ||
ioServer = socketIO(server).listen(port); | ||
ioRxjs = new SocketIORxjs(`http://localhost:${port}`); | ||
}); | ||
|
||
afterEach(() => { | ||
ioRxjs.close(); | ||
ioServer.close(); | ||
}); | ||
|
||
it('subscribe onopen', (done) => { | ||
const msg = { | ||
action: 'test', | ||
}; | ||
ioRxjs.message$.subscribe((o) => { | ||
ioRxjs.send(['test', msg]); | ||
expect(o).toEqual(msg); | ||
}); | ||
ioServer.on('connection', (ws) => { | ||
ws.send(msg); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('send message', (done) => { | ||
const msg = { | ||
action: 'test', | ||
}; | ||
ioRxjs.message$.subscribe((o) => { | ||
ioRxjs.send(msg); | ||
}); | ||
|
||
ioServer.on('connection', (ws) => { | ||
ws.send(msg); | ||
ws.on('message', (data) => { | ||
expect(data).toEqual(msg); | ||
}); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('subscribe onmessage to exception', (done) => { | ||
ioServer.on('connection', (ws) => { | ||
ws.send('t'); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('subscribe onerror', (done) => { | ||
ioServer.on('connection', () => { | ||
ioServer.emit('error', new Error('xxx erorr')); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('subscribe connect_timeout', (done) => { | ||
ioServer.on('connection', () => { | ||
ioServer.emit('connect_timeout', new Error('erorr: cant not connection')); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('subscribe connect_error', (done) => { | ||
const ws = new SocketIORxjs(`http://localhost:8801`); | ||
|
||
expect(ws).toBeDefined(); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
|
||
it('join room', (done) => { | ||
const roomName = 'event_room'; | ||
const msg = { | ||
toEveryone: 'Hi', | ||
}; | ||
const joinMsg = { | ||
name: 'jack', | ||
}; | ||
|
||
ioRxjs.message$.subscribe((data) => { | ||
expect(data).toEqual(msg); | ||
}); | ||
|
||
ioRxjs.emit('joinRoom', [roomName, joinMsg]); | ||
ioServer.on('connection', (ws) => { | ||
ws.on('joinRoom', (roomNm, data) => { | ||
ws.join(roomNm); | ||
expect(data).toEqual(joinMsg); | ||
}); | ||
}); | ||
setTimeout(() => { | ||
ioServer.to(roomName).emit('message', msg); | ||
}, 500); | ||
setTimeout(() => { | ||
done(); | ||
}, 1000); | ||
}); | ||
|
||
it('custom event', (done) => { | ||
const event = 'foo'; | ||
const msg = { | ||
toEveryone: 'Hi', | ||
}; | ||
ioRxjs.message$.subscribe((data) => { | ||
expect(data).toEqual('ok'); | ||
}); | ||
|
||
ioRxjs.emit(event, msg); | ||
ioServer.on('connection', (ws) => { | ||
ws.on(event, (data) => { | ||
ioServer.send('ok'); | ||
expect(data).toEqual(msg); | ||
}); | ||
}); | ||
setTimeout(() => { | ||
done(); | ||
}, 500); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { Observable, ReplaySubject } from 'rxjs'; | ||
import { filter, take } from 'rxjs/operators'; | ||
import * as io from 'socket.io-client'; | ||
|
||
export class SocketIORxjs<T = any> { | ||
readonly socket: SocketIOClient.Socket; | ||
private readonly data$ = new ReplaySubject<T>(1); | ||
private readonly opened$ = new ReplaySubject<boolean>(1); | ||
|
||
/** | ||
* message stream | ||
*/ | ||
get message$(): Observable<T> { | ||
return this.data$.asObservable(); | ||
} | ||
|
||
constructor(url: string) { | ||
this.socket = io(url); | ||
this.socket.on('connect', () => { | ||
this.opened$.next(true); | ||
}); | ||
this.socket.on('connect_timeout', () => { | ||
this.opened$.next(false); | ||
}); | ||
this.socket.on('connect_error', () => { | ||
this.opened$.next(false); | ||
}); | ||
this.socket.on('disconnect', () => { | ||
this.opened$.next(false); | ||
}); | ||
this.socket.on('error', () => { | ||
this.opened$.next(false); | ||
}); | ||
this.socket.on('message', (data: any) => this.data$.next(data)); | ||
} | ||
|
||
/** | ||
* @param args | ||
*/ | ||
send(args: any | any[]): void { | ||
// wait until socket open and send the text only once per call | ||
this.opened$ | ||
.pipe( | ||
take(1), | ||
filter((opened) => opened), | ||
) | ||
.subscribe(() => { | ||
if (args instanceof Array) { | ||
this.socket.send(...args); | ||
} else { | ||
this.socket.send(args); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* @param args | ||
*/ | ||
emit(event: string, args: any | any[]): void { | ||
// wait until socket open and send the text only once per call | ||
this.opened$ | ||
.pipe( | ||
take(1), | ||
filter((opened) => opened), | ||
) | ||
.subscribe(() => { | ||
if (args instanceof Array) { | ||
this.socket.emit(event, ...args); | ||
} else { | ||
this.socket.emit(event, args); | ||
} | ||
}); | ||
} | ||
|
||
close(): void { | ||
this.socket.close(); | ||
this.data$.complete(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { ConnectionOptions } from 'typeorm'; | ||
|
||
export interface Config { | ||
// config file name. for debug purpose. | ||
env: string; | ||
production: boolean; | ||
database: Partial<ConnectionOptions>; | ||
container: ConfigContainer; | ||
exchange: ConfigExchange; | ||
log: { | ||
typeorm: boolean; | ||
}; | ||
} | ||
|
||
export interface ConfigContainer { | ||
intelService: ConfigIntelServer; | ||
} | ||
|
||
export interface ConfigIntelServer { | ||
port: number; | ||
username: string; | ||
password: number; | ||
} | ||
|
||
export interface ConfigExchange { | ||
[type: string]: ConfigExchangeCrypto; | ||
} | ||
|
||
export interface ConfigExchangeCrypto { | ||
[exchange: string]: ExchangeCryptoAuthConfig; | ||
} | ||
|
||
export interface ExchangeCryptoAuthConfig { | ||
apiKey: string; | ||
apiSecret: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.