-
Notifications
You must be signed in to change notification settings - Fork 33
/
index.ts
118 lines (94 loc) · 4.33 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import io from 'socket.io-client';
import socketIO from 'socket.io';
import config, { DEFAULT_CORE_SOCKET_PORT } from 'shared/config/index';
import { API_SOCKET_SERVER_CONFIG, PEER_SOCKET_CLIENT_CONFIG } from 'shared/config/socket';
import { messageON } from 'shared/util/bus';
import { logger } from 'shared/util/logger';
import { IPRegExp } from 'core/util/common';
import { PEER_SOCKET_TYPE, PeerAddress } from 'shared/model/types';
import { ActionTypes } from 'core/util/actionTypes';
import { SerializedFullHeaders } from 'shared/model/Peer/fullHeaders';
import { PEER_SOCKET_EVENTS } from 'core/driver/socket/socketsTypes';
import { peerAddressToString } from 'core/util/peer';
import { createBufferObject, deserialize } from 'shared/util/byteSerializer';
import { SchemaName } from 'shared/util/byteSerializer/config';
export const REQUEST_TIMEOUT = '408 Request Timeout';
export class Socket {
private static instance: Socket;
private static ioServer;
constructor() {
if (Socket.instance) {
return Socket.instance;
}
Socket.instance = this;
}
initServer(): void {
Socket.ioServer = socketIO(config.CORE.SOCKET.PORT, API_SOCKET_SERVER_CONFIG);
logger.debug(`WebSocket listening on port ${config.CORE.SOCKET.PORT}`);
Socket.ioServer.on(PEER_SOCKET_EVENTS.CONNECT, Socket.instance.onServerConnect);
setTimeout(() => messageON(ActionTypes.PEER_CONNECT_RUN),
config.CONSTANTS.TIMEOUT_START_PEER_CONNECT);
setTimeout(() => messageON(ActionTypes.EMIT_REQUEST_PEERS),
config.CONSTANTS.TIMEOUT_START_PEER_REQUEST
);
}
onServerConnect(socket: socketIO.Socket): void {
const address = socket.handshake.address || socket.request.connection.remoteAddress;
if (!address) {
logger.warn(`[SOCKET][onServerConnect] socket handshake address is missing`);
socket.disconnect(true);
return;
}
const ip = address.match(IPRegExp).toString();
if (config.CORE.PEERS.BLACKLIST.indexOf(ip) !== -1) {
logger.warn(`[SOCKET][onServerConnect] trying to connect from black ip`);
socket.disconnect(true);
}
if (Socket.ioServer.clients().length > config.CONSTANTS.MAX_PEERS_CONNECTED) {
logger.warn(`[SOCKET][onServerConnect] too many connections, sorry ${ip}`);
socket.disconnect(true);
}
socket.on(PEER_SOCKET_EVENTS.HEADERS, (response: Buffer) => {
Socket.instance.onHeadersReceive(
response, {
ip,
port: DEFAULT_CORE_SOCKET_PORT
},
socket, PEER_SOCKET_TYPE.CLIENT);
}
);
}
connectPeer(peerAddress: PeerAddress, headers: SerializedFullHeaders): void {
logger.trace(`[SOCKET][connectPeer] connecting to ${peerAddressToString(peerAddress)}...`);
const ws: SocketIOClient.Socket = io(
`ws://${peerAddressToString(peerAddress)}`,
PEER_SOCKET_CLIENT_CONFIG
);
ws.on(PEER_SOCKET_EVENTS.CONNECT, () => {
logger.trace(`[SOCKET][connectPeer] connected to ${peerAddressToString(peerAddress)}`);
ws.emit(PEER_SOCKET_EVENTS.HEADERS, createBufferObject(headers, SchemaName.FullHeaders));
ws.on(PEER_SOCKET_EVENTS.HEADERS, (response: Buffer) => {
Socket.instance.onHeadersReceive(response, peerAddress, ws, PEER_SOCKET_TYPE.SERVER);
});
});
}
onHeadersReceive(response: Buffer, peerAddress: PeerAddress, socket, type: PEER_SOCKET_TYPE) {
if (!Buffer.isBuffer(response)) {
logger.error(`[SOCKET][onHeadersReceive] ${peerAddressToString(peerAddress)} ` +
`as ${type} has sent: ${response}`);
socket.disconnect(true);
return;
}
const peerHeaders = deserialize(response);
logger.trace(`[Driver][Socket][onHeadersReceive] ${type} ${peerAddress.ip}, ` +
`broadhash: ${peerHeaders.broadhash}, height: ${peerHeaders.height}, ` +
`buffer size: ${response.length} byte`);
messageON(ActionTypes.HEADERS_RECEIVE, {
peerAddress,
peerHeaders,
socket,
type: type,
});
}
}
export default new Socket();