Merge pull request #5035 from mempool/mononaut/accelerator-websocket
Replace acceleration API polling with websocket
This commit is contained in:
commit
feab4d2a51
@ -404,6 +404,10 @@ class Mempool {
|
|||||||
|
|
||||||
const newAccelerationMap: { [txid: string]: Acceleration } = {};
|
const newAccelerationMap: { [txid: string]: Acceleration } = {};
|
||||||
for (const acceleration of newAccelerations) {
|
for (const acceleration of newAccelerations) {
|
||||||
|
// skip transactions we don't know about
|
||||||
|
if (!this.mempoolCache[acceleration.txid]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
newAccelerationMap[acceleration.txid] = acceleration;
|
newAccelerationMap[acceleration.txid] = acceleration;
|
||||||
if (this.accelerations[acceleration.txid] == null) {
|
if (this.accelerations[acceleration.txid] == null) {
|
||||||
// new acceleration
|
// new acceleration
|
||||||
|
@ -347,6 +347,17 @@ class WebsocketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parsedMessage && parsedMessage['track-accelerations'] != null) {
|
||||||
|
if (parsedMessage['track-accelerations']) {
|
||||||
|
client['track-accelerations'] = true;
|
||||||
|
response['accelerations'] = JSON.stringify({
|
||||||
|
accelerations: Object.values(memPool.getAccelerations()),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
client['track-accelerations'] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parsedMessage.action === 'init') {
|
if (parsedMessage.action === 'init') {
|
||||||
if (!this.socketData['blocks']?.length || !this.socketData['da'] || !this.socketData['backendInfo'] || !this.socketData['conversions']) {
|
if (!this.socketData['blocks']?.length || !this.socketData['da'] || !this.socketData['backendInfo'] || !this.socketData['conversions']) {
|
||||||
this.updateSocketData();
|
this.updateSocketData();
|
||||||
@ -537,6 +548,7 @@ class WebsocketHandler {
|
|||||||
const vBytesPerSecond = memPool.getVBytesPerSecond();
|
const vBytesPerSecond = memPool.getVBytesPerSecond();
|
||||||
const rbfTransactions = Common.findRbfTransactions(newTransactions, deletedTransactions);
|
const rbfTransactions = Common.findRbfTransactions(newTransactions, deletedTransactions);
|
||||||
const da = difficultyAdjustment.getDifficultyAdjustment();
|
const da = difficultyAdjustment.getDifficultyAdjustment();
|
||||||
|
const accelerations = memPool.getAccelerations();
|
||||||
memPool.handleRbfTransactions(rbfTransactions);
|
memPool.handleRbfTransactions(rbfTransactions);
|
||||||
const rbfChanges = rbfCache.getRbfChanges();
|
const rbfChanges = rbfCache.getRbfChanges();
|
||||||
let rbfReplacements;
|
let rbfReplacements;
|
||||||
@ -644,6 +656,12 @@ class WebsocketHandler {
|
|||||||
const addressCache = this.makeAddressCache(newTransactions);
|
const addressCache = this.makeAddressCache(newTransactions);
|
||||||
const removedAddressCache = this.makeAddressCache(deletedTransactions);
|
const removedAddressCache = this.makeAddressCache(deletedTransactions);
|
||||||
|
|
||||||
|
// pre-compute acceleration delta
|
||||||
|
const accelerationUpdate = {
|
||||||
|
added: accelerationDelta.map(txid => accelerations[txid]).filter(acc => acc != null),
|
||||||
|
removed: accelerationDelta.filter(txid => !accelerations[txid]),
|
||||||
|
};
|
||||||
|
|
||||||
// TODO - Fix indentation after PR is merged
|
// TODO - Fix indentation after PR is merged
|
||||||
for (const server of this.webSocketServers) {
|
for (const server of this.webSocketServers) {
|
||||||
server.clients.forEach(async (client) => {
|
server.clients.forEach(async (client) => {
|
||||||
@ -891,6 +909,10 @@ class WebsocketHandler {
|
|||||||
response['mempool-transactions'] = getCachedResponse('mempool-transactions', mempoolDelta);
|
response['mempool-transactions'] = getCachedResponse('mempool-transactions', mempoolDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client['track-accelerations'] && (accelerationUpdate.added.length || accelerationUpdate.removed.length)) {
|
||||||
|
response['accelerations'] = getCachedResponse('accelerations', accelerationUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(response).length) {
|
if (Object.keys(response).length) {
|
||||||
client.send(this.serializeResponse(response));
|
client.send(this.serializeResponse(response));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core';
|
import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnDestroy } from '@angular/core';
|
||||||
import { combineLatest, BehaviorSubject, Observable, catchError, of, switchMap, tap } from 'rxjs';
|
import { BehaviorSubject, Observable, catchError, of, switchMap, tap } from 'rxjs';
|
||||||
import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
|
import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
|
||||||
import { StateService } from '../../../services/state.service';
|
import { StateService } from '../../../services/state.service';
|
||||||
import { WebsocketService } from '../../../services/websocket.service';
|
import { WebsocketService } from '../../../services/websocket.service';
|
||||||
@ -11,7 +11,7 @@ import { ServicesApiServices } from '../../../services/services-api.service';
|
|||||||
styleUrls: ['./accelerations-list.component.scss'],
|
styleUrls: ['./accelerations-list.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AccelerationsListComponent implements OnInit {
|
export class AccelerationsListComponent implements OnInit, OnDestroy {
|
||||||
@Input() widget: boolean = false;
|
@Input() widget: boolean = false;
|
||||||
@Input() pending: boolean = false;
|
@Input() pending: boolean = false;
|
||||||
@Input() accelerations$: Observable<Acceleration[]>;
|
@Input() accelerations$: Observable<Acceleration[]>;
|
||||||
@ -44,7 +44,10 @@ export class AccelerationsListComponent implements OnInit {
|
|||||||
|
|
||||||
this.accelerationList$ = this.pageSubject.pipe(
|
this.accelerationList$ = this.pageSubject.pipe(
|
||||||
switchMap((page) => {
|
switchMap((page) => {
|
||||||
const accelerationObservable$ = this.accelerations$ || (this.pending ? this.servicesApiService.getAccelerations$() : this.servicesApiService.getAccelerationHistoryObserveResponse$({ page: page }));
|
const accelerationObservable$ = this.accelerations$ || (this.pending ? this.stateService.liveAccelerations$ : this.servicesApiService.getAccelerationHistoryObserveResponse$({ page: page }));
|
||||||
|
if (!this.accelerations$ && this.pending) {
|
||||||
|
this.websocketService.ensureTrackAccelerations();
|
||||||
|
}
|
||||||
return accelerationObservable$.pipe(
|
return accelerationObservable$.pipe(
|
||||||
switchMap(response => {
|
switchMap(response => {
|
||||||
let accelerations = response;
|
let accelerations = response;
|
||||||
@ -85,4 +88,8 @@ export class AccelerationsListComponent implements OnInit {
|
|||||||
trackByBlock(index: number, block: BlockExtended): number {
|
trackByBlock(index: number, block: BlockExtended): number {
|
||||||
return block.height;
|
return block.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.websocketService.stopTrackAccelerations();
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import { ChangeDetectionStrategy, Component, HostListener, Inject, OnInit, PLATFORM_ID } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, HostListener, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
|
||||||
import { SeoService } from '../../../services/seo.service';
|
import { SeoService } from '../../../services/seo.service';
|
||||||
import { OpenGraphService } from '../../../services/opengraph.service';
|
import { OpenGraphService } from '../../../services/opengraph.service';
|
||||||
import { WebsocketService } from '../../../services/websocket.service';
|
import { WebsocketService } from '../../../services/websocket.service';
|
||||||
import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
|
import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
|
||||||
import { StateService } from '../../../services/state.service';
|
import { StateService } from '../../../services/state.service';
|
||||||
import { Observable, catchError, combineLatest, distinctUntilChanged, interval, map, of, share, startWith, switchMap, tap } from 'rxjs';
|
import { Observable, Subscription, catchError, combineLatest, distinctUntilChanged, map, of, share, switchMap, tap } from 'rxjs';
|
||||||
import { Color } from '../../block-overview-graph/sprite-types';
|
import { Color } from '../../block-overview-graph/sprite-types';
|
||||||
import { hexToColor } from '../../block-overview-graph/utils';
|
import { hexToColor } from '../../block-overview-graph/utils';
|
||||||
import TxView from '../../block-overview-graph/tx-view';
|
import TxView from '../../block-overview-graph/tx-view';
|
||||||
@ -28,7 +28,7 @@ interface AccelerationBlock extends BlockExtended {
|
|||||||
styleUrls: ['./accelerator-dashboard.component.scss'],
|
styleUrls: ['./accelerator-dashboard.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AcceleratorDashboardComponent implements OnInit {
|
export class AcceleratorDashboardComponent implements OnInit, OnDestroy {
|
||||||
blocks$: Observable<AccelerationBlock[]>;
|
blocks$: Observable<AccelerationBlock[]>;
|
||||||
accelerations$: Observable<Acceleration[]>;
|
accelerations$: Observable<Acceleration[]>;
|
||||||
pendingAccelerations$: Observable<Acceleration[]>;
|
pendingAccelerations$: Observable<Acceleration[]>;
|
||||||
@ -39,6 +39,8 @@ export class AcceleratorDashboardComponent implements OnInit {
|
|||||||
firstLoad = true;
|
firstLoad = true;
|
||||||
timespan: '3d' | '1w' | '1m' = '1w';
|
timespan: '3d' | '1w' | '1m' = '1w';
|
||||||
|
|
||||||
|
accelerationDeltaSubscription: Subscription;
|
||||||
|
|
||||||
graphHeight: number = 300;
|
graphHeight: number = 300;
|
||||||
theme: ThemeService;
|
theme: ThemeService;
|
||||||
|
|
||||||
@ -59,27 +61,28 @@ export class AcceleratorDashboardComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.onResize();
|
this.onResize();
|
||||||
this.websocketService.want(['blocks', 'mempool-blocks', 'stats']);
|
this.websocketService.want(['blocks', 'mempool-blocks', 'stats']);
|
||||||
|
this.websocketService.startTrackAccelerations();
|
||||||
|
|
||||||
this.pendingAccelerations$ = (this.stateService.isBrowser ? interval(30000) : of(null)).pipe(
|
this.pendingAccelerations$ = this.stateService.liveAccelerations$.pipe(
|
||||||
startWith(true),
|
|
||||||
switchMap(() => {
|
|
||||||
return this.serviceApiServices.getAccelerations$().pipe(
|
|
||||||
catchError(() => {
|
|
||||||
return of([]);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
tap(accelerations => {
|
|
||||||
if (!this.firstLoad && accelerations.some(acc => !this.seen.has(acc.txid))) {
|
|
||||||
this.audioService.playSound('bright-harmony');
|
|
||||||
}
|
|
||||||
for(const acc of accelerations) {
|
|
||||||
this.seen.add(acc.txid);
|
|
||||||
}
|
|
||||||
this.firstLoad = false;
|
|
||||||
}),
|
|
||||||
share(),
|
share(),
|
||||||
);
|
);
|
||||||
|
this.accelerationDeltaSubscription = this.stateService.accelerations$.subscribe((delta) => {
|
||||||
|
if (!delta.reset) {
|
||||||
|
let hasNewAcceleration = false;
|
||||||
|
for (const acc of delta.added) {
|
||||||
|
if (!this.seen.has(acc.txid)) {
|
||||||
|
hasNewAcceleration = true;
|
||||||
|
}
|
||||||
|
this.seen.add(acc.txid);
|
||||||
|
}
|
||||||
|
for (const txid of delta.removed) {
|
||||||
|
this.seen.delete(txid);
|
||||||
|
}
|
||||||
|
if (hasNewAcceleration) {
|
||||||
|
this.audioService.playSound('bright-harmony');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.accelerations$ = this.stateService.chainTip$.pipe(
|
this.accelerations$ = this.stateService.chainTip$.pipe(
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
@ -154,6 +157,11 @@ export class AcceleratorDashboardComponent implements OnInit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.accelerationDeltaSubscription.unsubscribe();
|
||||||
|
this.websocketService.stopTrackAccelerations();
|
||||||
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
onResize(): void {
|
onResize(): void {
|
||||||
if (window.innerWidth >= 992) {
|
if (window.innerWidth >= 992) {
|
||||||
|
@ -2,7 +2,8 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core
|
|||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { switchMap } from 'rxjs/operators';
|
import { switchMap } from 'rxjs/operators';
|
||||||
import { Acceleration } from '../../../interfaces/node-api.interface';
|
import { Acceleration } from '../../../interfaces/node-api.interface';
|
||||||
import { ServicesApiServices } from '../../../services/services-api.service';
|
import { StateService } from '../../../services/state.service';
|
||||||
|
import { WebsocketService } from '../../../services/websocket.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pending-stats',
|
selector: 'app-pending-stats',
|
||||||
@ -15,11 +16,12 @@ export class PendingStatsComponent implements OnInit {
|
|||||||
public accelerationStats$: Observable<any>;
|
public accelerationStats$: Observable<any>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private servicesApiService: ServicesApiServices,
|
private stateService: StateService,
|
||||||
|
private websocketService: WebsocketService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.accelerationStats$ = (this.accelerations$ || this.servicesApiService.getAccelerations$()).pipe(
|
this.accelerationStats$ = (this.accelerations$ || this.stateService.liveAccelerations$).pipe(
|
||||||
switchMap(accelerations => {
|
switchMap(accelerations => {
|
||||||
let totalAccelerations = 0;
|
let totalAccelerations = 0;
|
||||||
let totalFeeDelta = 0;
|
let totalFeeDelta = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { SafeResourceUrl } from '@angular/platform-browser';
|
import { SafeResourceUrl } from '@angular/platform-browser';
|
||||||
import { ILoadingIndicators } from '../services/state.service';
|
import { ILoadingIndicators } from '../services/state.service';
|
||||||
import { Transaction } from './electrs.interface';
|
import { Transaction } from './electrs.interface';
|
||||||
import { BlockExtended, DifficultyAdjustment, RbfTree, TransactionStripped } from './node-api.interface';
|
import { Acceleration, BlockExtended, DifficultyAdjustment, RbfTree, TransactionStripped } from './node-api.interface';
|
||||||
|
|
||||||
export interface WebsocketResponse {
|
export interface WebsocketResponse {
|
||||||
backend?: 'esplora' | 'electrum' | 'none';
|
backend?: 'esplora' | 'electrum' | 'none';
|
||||||
@ -35,6 +35,7 @@ export interface WebsocketResponse {
|
|||||||
'track-mempool-block'?: number;
|
'track-mempool-block'?: number;
|
||||||
'track-rbf'?: string;
|
'track-rbf'?: string;
|
||||||
'track-rbf-summary'?: boolean;
|
'track-rbf-summary'?: boolean;
|
||||||
|
'track-accelerations'?: boolean;
|
||||||
'watch-mempool'?: boolean;
|
'watch-mempool'?: boolean;
|
||||||
'refresh-blocks'?: boolean;
|
'refresh-blocks'?: boolean;
|
||||||
}
|
}
|
||||||
@ -92,6 +93,12 @@ export interface MempoolBlockDeltaCompressed {
|
|||||||
changed: MempoolDeltaChange[];
|
changed: MempoolDeltaChange[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AccelerationDelta {
|
||||||
|
added: Acceleration[];
|
||||||
|
removed: string[];
|
||||||
|
reset?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MempoolInfo {
|
export interface MempoolInfo {
|
||||||
loaded: boolean; // (boolean) True if the mempool is fully loaded
|
loaded: boolean; // (boolean) True if the mempool is fully loaded
|
||||||
size: number; // (numeric) Current tx count
|
size: number; // (numeric) Current tx count
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
|
import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
|
||||||
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable, merge } from 'rxjs';
|
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs';
|
||||||
import { Transaction } from '../interfaces/electrs.interface';
|
import { Transaction } from '../interfaces/electrs.interface';
|
||||||
import { HealthCheckHost, IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolBlockUpdate, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, isMempoolState } from '../interfaces/websocket.interface';
|
import { AccelerationDelta, HealthCheckHost, IBackendInfo, MempoolBlock, MempoolBlockUpdate, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, isMempoolState } from '../interfaces/websocket.interface';
|
||||||
import { BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree, TransactionStripped } from '../interfaces/node-api.interface';
|
import { Acceleration, BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree, TransactionStripped } from '../interfaces/node-api.interface';
|
||||||
import { Router, NavigationStart } from '@angular/router';
|
import { Router, NavigationStart } from '@angular/router';
|
||||||
import { isPlatformBrowser } from '@angular/common';
|
import { isPlatformBrowser } from '@angular/common';
|
||||||
import { filter, map, scan, shareReplay } from 'rxjs/operators';
|
import { filter, map, scan, shareReplay } from 'rxjs/operators';
|
||||||
@ -129,6 +129,8 @@ export class StateService {
|
|||||||
mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
|
mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
|
||||||
mempoolBlockUpdate$ = new Subject<MempoolBlockUpdate>();
|
mempoolBlockUpdate$ = new Subject<MempoolBlockUpdate>();
|
||||||
liveMempoolBlockTransactions$: Observable<{ [txid: string]: TransactionStripped}>;
|
liveMempoolBlockTransactions$: Observable<{ [txid: string]: TransactionStripped}>;
|
||||||
|
accelerations$ = new Subject<AccelerationDelta>();
|
||||||
|
liveAccelerations$: Observable<Acceleration[]>;
|
||||||
txConfirmed$ = new Subject<[string, BlockExtended]>();
|
txConfirmed$ = new Subject<[string, BlockExtended]>();
|
||||||
txReplaced$ = new Subject<ReplacedTransaction>();
|
txReplaced$ = new Subject<ReplacedTransaction>();
|
||||||
txRbfInfo$ = new Subject<RbfTree>();
|
txRbfInfo$ = new Subject<RbfTree>();
|
||||||
@ -238,6 +240,24 @@ export class StateService {
|
|||||||
}
|
}
|
||||||
}, {}));
|
}, {}));
|
||||||
|
|
||||||
|
// Emits the full list of pending accelerations each time it changes
|
||||||
|
this.liveAccelerations$ = this.accelerations$.pipe(
|
||||||
|
scan((accelerations: { [txid: string]: Acceleration }, delta: AccelerationDelta) => {
|
||||||
|
if (delta.reset) {
|
||||||
|
accelerations = {};
|
||||||
|
} else {
|
||||||
|
for (const txid of delta.removed) {
|
||||||
|
delete accelerations[txid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const acc of delta.added) {
|
||||||
|
accelerations[acc.txid] = acc;
|
||||||
|
}
|
||||||
|
return accelerations;
|
||||||
|
}, {}),
|
||||||
|
map((accMap) => Object.values(accMap).sort((a,b) => b.added - a.added))
|
||||||
|
);
|
||||||
|
|
||||||
this.networkChanged$.subscribe((network) => {
|
this.networkChanged$.subscribe((network) => {
|
||||||
this.transactions$ = new BehaviorSubject<TransactionStripped[]>(null);
|
this.transactions$ = new BehaviorSubject<TransactionStripped[]>(null);
|
||||||
this.blocksSubject$.next([]);
|
this.blocksSubject$.next([]);
|
||||||
|
@ -33,6 +33,7 @@ export class WebsocketService {
|
|||||||
private isTrackingRbfSummary = false;
|
private isTrackingRbfSummary = false;
|
||||||
private isTrackingAddress: string | false = false;
|
private isTrackingAddress: string | false = false;
|
||||||
private isTrackingAddresses: string[] | false = false;
|
private isTrackingAddresses: string[] | false = false;
|
||||||
|
private isTrackingAccelerations: boolean = false;
|
||||||
private trackingMempoolBlock: number;
|
private trackingMempoolBlock: number;
|
||||||
private latestGitCommit = '';
|
private latestGitCommit = '';
|
||||||
private onlineCheckTimeout: number;
|
private onlineCheckTimeout: number;
|
||||||
@ -132,6 +133,9 @@ export class WebsocketService {
|
|||||||
if (this.isTrackingAddresses) {
|
if (this.isTrackingAddresses) {
|
||||||
this.startTrackAddresses(this.isTrackingAddresses);
|
this.startTrackAddresses(this.isTrackingAddresses);
|
||||||
}
|
}
|
||||||
|
if (this.isTrackingAccelerations) {
|
||||||
|
this.startTrackAccelerations();
|
||||||
|
}
|
||||||
this.stateService.connectionState$.next(2);
|
this.stateService.connectionState$.next(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +239,24 @@ export class WebsocketService {
|
|||||||
this.isTrackingRbfSummary = false;
|
this.isTrackingRbfSummary = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startTrackAccelerations() {
|
||||||
|
this.websocketSubject.next({ 'track-accelerations': true });
|
||||||
|
this.isTrackingAccelerations = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stopTrackAccelerations() {
|
||||||
|
if (this.isTrackingAccelerations) {
|
||||||
|
this.websocketSubject.next({ 'track-accelerations': false });
|
||||||
|
this.isTrackingAccelerations = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureTrackAccelerations() {
|
||||||
|
if (!this.isTrackingAccelerations) {
|
||||||
|
this.startTrackAccelerations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fetchStatistics(historicalDate: string) {
|
fetchStatistics(historicalDate: string) {
|
||||||
this.websocketSubject.next({ historicalDate });
|
this.websocketSubject.next({ historicalDate });
|
||||||
}
|
}
|
||||||
@ -416,6 +438,18 @@ export class WebsocketService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response['accelerations']) {
|
||||||
|
if (response['accelerations'].accelerations) {
|
||||||
|
this.stateService.accelerations$.next({
|
||||||
|
added: response['accelerations'].accelerations,
|
||||||
|
removed: [],
|
||||||
|
reset: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.stateService.accelerations$.next(response['accelerations']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (response['live-2h-chart']) {
|
if (response['live-2h-chart']) {
|
||||||
this.stateService.live2Chart$.next(response['live-2h-chart']);
|
this.stateService.live2Chart$.next(response['live-2h-chart']);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user