optimize websocket init data
This commit is contained in:
parent
f8636d20c2
commit
ffd7831efc
@ -130,8 +130,9 @@ class BitcoinRoutes {
|
|||||||
|
|
||||||
private getInitData(req: Request, res: Response) {
|
private getInitData(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
const result = websocketHandler.getInitData();
|
const result = websocketHandler.getSerializedInitData();
|
||||||
res.json(result);
|
res.set('Content-Type', 'application/json');
|
||||||
|
res.send(result);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).send(e instanceof Error ? e.message : e);
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@ class WebsocketHandler {
|
|||||||
private numConnected = 0;
|
private numConnected = 0;
|
||||||
private numDisconnected = 0;
|
private numDisconnected = 0;
|
||||||
|
|
||||||
|
private initData: { [key: string]: string } = {};
|
||||||
|
private serializedInitData: string = '{}';
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
setWebsocketServer(wss: WebSocket.Server) {
|
setWebsocketServer(wss: WebSocket.Server) {
|
||||||
@ -38,6 +41,41 @@ class WebsocketHandler {
|
|||||||
|
|
||||||
setExtraInitProperties(property: string, value: any) {
|
setExtraInitProperties(property: string, value: any) {
|
||||||
this.extraInitProperties[property] = value;
|
this.extraInitProperties[property] = value;
|
||||||
|
this.setInitDataFields(this.extraInitProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setInitDataFields(data: { [property: string]: any }): void {
|
||||||
|
for (const property of Object.keys(data)) {
|
||||||
|
if (data[property] != null) {
|
||||||
|
this.initData[property] = JSON.stringify(data[property]);
|
||||||
|
} else {
|
||||||
|
delete this.initData[property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.serializedInitData = '{'
|
||||||
|
+ Object.keys(this.initData).map(key => `"${key}": ${this.initData[key]}`).join(', ')
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateInitData(): void {
|
||||||
|
const _blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
||||||
|
const da = difficultyAdjustment.getDifficultyAdjustment();
|
||||||
|
this.setInitDataFields({
|
||||||
|
'mempoolInfo': memPool.getMempoolInfo(),
|
||||||
|
'vBytesPerSecond': memPool.getVBytesPerSecond(),
|
||||||
|
'blocks': _blocks,
|
||||||
|
'conversions': priceUpdater.getLatestPrices(),
|
||||||
|
'mempool-blocks': mempoolBlocks.getMempoolBlocks(),
|
||||||
|
'transactions': memPool.getLatestTransactions(),
|
||||||
|
'backendInfo': backendInfo.getBackendInfo(),
|
||||||
|
'loadingIndicators': loadingIndicators.getLoadingIndicators(),
|
||||||
|
'da': da?.previousTime ? da : undefined,
|
||||||
|
'fees': feeApi.getRecommendedFee(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSerializedInitData(): string {
|
||||||
|
return this.serializedInitData;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupConnectionHandling() {
|
setupConnectionHandling() {
|
||||||
@ -157,11 +195,13 @@ class WebsocketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parsedMessage.action === 'init') {
|
if (parsedMessage.action === 'init') {
|
||||||
const _blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
if (!this.initData['blocks']?.length || !this.initData['da']) {
|
||||||
if (!_blocks) {
|
this.updateInitData();
|
||||||
|
}
|
||||||
|
if (!this.initData['blocks']?.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client.send(JSON.stringify(this.getInitData(_blocks)));
|
client.send(this.serializedInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsedMessage.action === 'ping') {
|
if (parsedMessage.action === 'ping') {
|
||||||
@ -210,6 +250,8 @@ class WebsocketHandler {
|
|||||||
throw new Error('WebSocket.Server is not set');
|
throw new Error('WebSocket.Server is not set');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setInitDataFields({ 'loadingIndicators': indicators });
|
||||||
|
|
||||||
const response = JSON.stringify({ loadingIndicators: indicators });
|
const response = JSON.stringify({ loadingIndicators: indicators });
|
||||||
this.wss.clients.forEach((client) => {
|
this.wss.clients.forEach((client) => {
|
||||||
if (client.readyState !== WebSocket.OPEN) {
|
if (client.readyState !== WebSocket.OPEN) {
|
||||||
@ -224,6 +266,8 @@ class WebsocketHandler {
|
|||||||
throw new Error('WebSocket.Server is not set');
|
throw new Error('WebSocket.Server is not set');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setInitDataFields({ 'conversions': conversionRates });
|
||||||
|
|
||||||
const response = JSON.stringify({ conversions: conversionRates });
|
const response = JSON.stringify({ conversions: conversionRates });
|
||||||
this.wss.clients.forEach((client) => {
|
this.wss.clients.forEach((client) => {
|
||||||
if (client.readyState !== WebSocket.OPEN) {
|
if (client.readyState !== WebSocket.OPEN) {
|
||||||
@ -233,26 +277,6 @@ class WebsocketHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getInitData(_blocks?: BlockExtended[]) {
|
|
||||||
if (!_blocks) {
|
|
||||||
_blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
|
||||||
}
|
|
||||||
const da = difficultyAdjustment.getDifficultyAdjustment();
|
|
||||||
return {
|
|
||||||
'mempoolInfo': memPool.getMempoolInfo(),
|
|
||||||
'vBytesPerSecond': memPool.getVBytesPerSecond(),
|
|
||||||
'blocks': _blocks,
|
|
||||||
'conversions': priceUpdater.getLatestPrices(),
|
|
||||||
'mempool-blocks': mempoolBlocks.getMempoolBlocks(),
|
|
||||||
'transactions': memPool.getLatestTransactions(),
|
|
||||||
'backendInfo': backendInfo.getBackendInfo(),
|
|
||||||
'loadingIndicators': loadingIndicators.getLoadingIndicators(),
|
|
||||||
'da': da?.previousTime ? da : undefined,
|
|
||||||
'fees': feeApi.getRecommendedFee(),
|
|
||||||
...this.extraInitProperties
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNewStatistic(stats: OptimizedStatistic) {
|
handleNewStatistic(stats: OptimizedStatistic) {
|
||||||
if (!this.wss) {
|
if (!this.wss) {
|
||||||
throw new Error('WebSocket.Server is not set');
|
throw new Error('WebSocket.Server is not set');
|
||||||
@ -310,8 +334,11 @@ class WebsocketHandler {
|
|||||||
}
|
}
|
||||||
const recommendedFees = feeApi.getRecommendedFee();
|
const recommendedFees = feeApi.getRecommendedFee();
|
||||||
|
|
||||||
|
// update init data
|
||||||
|
this.updateInitData();
|
||||||
|
|
||||||
// cache serialized objects to avoid stringify-ing the same thing for every client
|
// cache serialized objects to avoid stringify-ing the same thing for every client
|
||||||
const responseCache = {};
|
const responseCache = { ...this.initData };
|
||||||
function getCachedResponse(key: string, data): string {
|
function getCachedResponse(key: string, data): string {
|
||||||
if (!responseCache[key]) {
|
if (!responseCache[key]) {
|
||||||
responseCache[key] = JSON.stringify(data);
|
responseCache[key] = JSON.stringify(data);
|
||||||
@ -342,6 +369,8 @@ class WebsocketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const latestTransactions = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
|
||||||
|
|
||||||
this.wss.clients.forEach(async (client) => {
|
this.wss.clients.forEach(async (client) => {
|
||||||
if (client.readyState !== WebSocket.OPEN) {
|
if (client.readyState !== WebSocket.OPEN) {
|
||||||
return;
|
return;
|
||||||
@ -352,7 +381,7 @@ class WebsocketHandler {
|
|||||||
if (client['want-stats']) {
|
if (client['want-stats']) {
|
||||||
response['mempoolInfo'] = getCachedResponse('mempoolInfo', mempoolInfo);
|
response['mempoolInfo'] = getCachedResponse('mempoolInfo', mempoolInfo);
|
||||||
response['vBytesPerSecond'] = getCachedResponse('vBytesPerSecond', vBytesPerSecond);
|
response['vBytesPerSecond'] = getCachedResponse('vBytesPerSecond', vBytesPerSecond);
|
||||||
response['transactions'] = getCachedResponse('transactions', newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx)));
|
response['transactions'] = getCachedResponse('transactions', latestTransactions);
|
||||||
if (da?.previousTime) {
|
if (da?.previousTime) {
|
||||||
response['da'] = getCachedResponse('da', da);
|
response['da'] = getCachedResponse('da', da);
|
||||||
}
|
}
|
||||||
@ -587,14 +616,19 @@ class WebsocketHandler {
|
|||||||
const da = difficultyAdjustment.getDifficultyAdjustment();
|
const da = difficultyAdjustment.getDifficultyAdjustment();
|
||||||
const fees = feeApi.getRecommendedFee();
|
const fees = feeApi.getRecommendedFee();
|
||||||
|
|
||||||
const responseCache = {};
|
// update init data
|
||||||
function getCachedResponse(key, data) {
|
this.updateInitData();
|
||||||
|
|
||||||
|
const responseCache = { ...this.initData };
|
||||||
|
function getCachedResponse(key, data): string {
|
||||||
if (!responseCache[key]) {
|
if (!responseCache[key]) {
|
||||||
responseCache[key] = JSON.stringify(data);
|
responseCache[key] = JSON.stringify(data);
|
||||||
}
|
}
|
||||||
return responseCache[key];
|
return responseCache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mempoolInfo = memPool.getMempoolInfo();
|
||||||
|
|
||||||
this.wss.clients.forEach((client) => {
|
this.wss.clients.forEach((client) => {
|
||||||
if (client.readyState !== WebSocket.OPEN) {
|
if (client.readyState !== WebSocket.OPEN) {
|
||||||
return;
|
return;
|
||||||
@ -606,7 +640,7 @@ class WebsocketHandler {
|
|||||||
|
|
||||||
const response = {};
|
const response = {};
|
||||||
response['block'] = getCachedResponse('block', block);
|
response['block'] = getCachedResponse('block', block);
|
||||||
response['mempoolInfo'] = getCachedResponse('mempoolInfo', memPool.getMempoolInfo(),);
|
response['mempoolInfo'] = getCachedResponse('mempoolInfo', mempoolInfo);
|
||||||
response['da'] = getCachedResponse('da', da?.previousTime ? da : undefined);
|
response['da'] = getCachedResponse('da', da?.previousTime ? da : undefined);
|
||||||
response['fees'] = getCachedResponse('fees', fees);
|
response['fees'] = getCachedResponse('fees', fees);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user