forked from ddrilling/asb_cloud_front
перед выходными:)
This commit is contained in:
parent
d4d51941d7
commit
ea426b16ef
16
package-lock.json
generated
16
package-lock.json
generated
@ -4189,6 +4189,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
|
||||||
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
|
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-DR0GmFSlxcFJp/w//ZmbxSduAkH/AqwxoiZxK97KHnWZf6gvsKWS3160WvNMMHYvzW9OXqGWjPjVh1Qu+xDabg=="
|
||||||
|
},
|
||||||
|
"chartjs-adapter-date-fns": {
|
||||||
|
"version": "1.1.0-beta.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-1.1.0-beta.1.tgz",
|
||||||
|
"integrity": "sha512-VNhuZ86kXKOwh61CyRLP7hoFqAR7+gjnrtf7KYLt/Wfh3jIQs14l1h+nagtQoFaabIYIo6UD5/jJb2/J6zOPcw=="
|
||||||
|
},
|
||||||
"check-types": {
|
"check-types": {
|
||||||
"version": "11.1.2",
|
"version": "11.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz",
|
||||||
@ -5060,9 +5070,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"date-fns": {
|
"date-fns": {
|
||||||
"version": "2.19.0",
|
"version": "2.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.20.0.tgz",
|
||||||
"integrity": "sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg=="
|
"integrity": "sha512-nmA7y6aDH5+fknfJ0G77HQzUSfTPpq4ifq+c9blP9d+X9zs3kNjxC+t3pcbBMGTp262a6PJB3RVjLlxIgoMI+Q=="
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
"@testing-library/react": "^11.2.6",
|
"@testing-library/react": "^11.2.6",
|
||||||
"@testing-library/user-event": "^12.8.3",
|
"@testing-library/user-event": "^12.8.3",
|
||||||
"antd": "^4.15.0",
|
"antd": "^4.15.0",
|
||||||
|
"chart.js": "^3.0.2",
|
||||||
|
"chartjs-adapter-date-fns": "^1.1.0-beta.1",
|
||||||
"craco-less": "^1.17.1",
|
"craco-less": "^1.17.1",
|
||||||
|
"date-fns": "^2.20.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
21
src/App.js
21
src/App.js
@ -3,30 +3,15 @@ import React /*, { useContext, createContext, useState }*/ from "react"
|
|||||||
import {
|
import {
|
||||||
BrowserRouter as Router,
|
BrowserRouter as Router,
|
||||||
Switch,
|
Switch,
|
||||||
Route,
|
Route} from "react-router-dom"
|
||||||
Redirect
|
|
||||||
} from "react-router-dom"
|
|
||||||
import Login from './pages/Login'
|
import Login from './pages/Login'
|
||||||
import Main from './pages/Main'
|
import Main from './pages/Main'
|
||||||
import {OpenAPI} from './services/api'
|
import { OpenAPI } from './services/api'
|
||||||
|
import { PrivateRoute } from './components/PrivateRoute'
|
||||||
|
|
||||||
OpenAPI.BASE = 'http://localhost:3000'
|
OpenAPI.BASE = 'http://localhost:3000'
|
||||||
OpenAPI.TOKEN = localStorage['token']
|
OpenAPI.TOKEN = localStorage['token']
|
||||||
|
|
||||||
function PrivateRoute({ children, ...rest }) {
|
|
||||||
let token = localStorage['token']
|
|
||||||
return (
|
|
||||||
<Route
|
|
||||||
{...rest}
|
|
||||||
render={({ location }) =>
|
|
||||||
token
|
|
||||||
? (children)
|
|
||||||
: (<Redirect to={{pathname: "/login", state: { from: location }}}/>)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
|
16
src/components/PrivateRoute.jsx
Normal file
16
src/components/PrivateRoute.jsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React /*, { useContext, createContext, useState }*/ from "react";
|
||||||
|
import {
|
||||||
|
Route,
|
||||||
|
Redirect
|
||||||
|
} from "react-router-dom";
|
||||||
|
|
||||||
|
export function PrivateRoute({ children, ...rest }) {
|
||||||
|
let token = localStorage['token'];
|
||||||
|
return (
|
||||||
|
<Route
|
||||||
|
{...rest}
|
||||||
|
render={({ location }) => token
|
||||||
|
? (children)
|
||||||
|
: (<Redirect to={{ pathname: "/login", state: { from: location } }} />)} />
|
||||||
|
);
|
||||||
|
}
|
69
src/components/charts/ChartSaubDataOnline.jsx
Normal file
69
src/components/charts/ChartSaubDataOnline.jsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { Chart, TimeScale, Legend, LineController, LineElement, PointElement } from 'chart.js'
|
||||||
|
import 'chartjs-adapter-date-fns';
|
||||||
|
import React, { useEffect, useRef} from 'react';
|
||||||
|
|
||||||
|
Chart.register( TimeScale, LineController, LineElement, PointElement, Legend );
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
//showLine :true,
|
||||||
|
indexAxis:'y',
|
||||||
|
//maintainAspectRatio: false,
|
||||||
|
//responsive:false,
|
||||||
|
scales: {
|
||||||
|
y:{
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
unit: 'second',
|
||||||
|
displayFormats: {
|
||||||
|
millisecond: 'HH:mm:ss.SSS',
|
||||||
|
second: 'HH:mm:ss',
|
||||||
|
minute: 'HH:mm:ss',
|
||||||
|
hour: 'dd HH:mm:ss',
|
||||||
|
day: 'MM.dd HH:mm',
|
||||||
|
week: 'yy.MM.dd HH:mm',
|
||||||
|
month: 'yyyy.MM.dd',
|
||||||
|
quarter: 'yyyy.MM.dd',
|
||||||
|
year: 'yyyy.MM',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const data= {
|
||||||
|
datasets: [{
|
||||||
|
label: 'Torque',
|
||||||
|
data: [
|
||||||
|
{x: 10, y: '2021-04-09T17:50:34.021679+05:00'},
|
||||||
|
{x: 15, y: '2021-04-09T17:50:33.021679+05:00'},
|
||||||
|
{x: 20, y: '2021-04-09T17:50:32.021679+05:00'}],
|
||||||
|
boderColor: 'rgba(0, 99, 132, 1)',
|
||||||
|
backgroundColor: 'rgba(0, 99, 132, 1)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pressure',
|
||||||
|
data: [
|
||||||
|
{x: 11, y: '2021-04-09T17:50:34.021679+05:00'},
|
||||||
|
{x: 14, y: '2021-04-09T17:50:33.021679+05:00'},
|
||||||
|
{x: 21, y: '2021-04-09T17:50:32.021679+05:00'}],
|
||||||
|
boderColor: 'rgba(255, 99, 132, 1)',
|
||||||
|
backgroundColor: 'rgba(255, 99, 132, 1)',
|
||||||
|
borderDash: [5, 5],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ChartSaubDataOnline(props){
|
||||||
|
const chartRef = useRef(null)
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
let chart = new Chart(chartRef.current, {
|
||||||
|
type: 'line',
|
||||||
|
data,
|
||||||
|
options})
|
||||||
|
//chart.canvas.parentNode.style.height = '128px';
|
||||||
|
return _ => chart.destroy()
|
||||||
|
},[])
|
||||||
|
|
||||||
|
return(<canvas ref={chartRef} />)
|
||||||
|
}
|
@ -32,13 +32,14 @@ export default function Login() {
|
|||||||
try{
|
try{
|
||||||
let user = await login(formData)
|
let user = await login(formData)
|
||||||
setUser(user)
|
setUser(user)
|
||||||
|
setLoader(false)
|
||||||
history.push('well')
|
history.push('well')
|
||||||
}catch(e){
|
}catch(e){
|
||||||
if(e.status === 400)
|
if(e.status === 400)
|
||||||
openNotificationError(e.message)
|
openNotificationError(e.message)
|
||||||
console.error(`Error ${e}`)
|
console.error(`Error ${e}`)
|
||||||
}
|
setLoader(false)
|
||||||
setLoader(false)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,30 @@
|
|||||||
|
import React, { useState, useEffect} from 'react';
|
||||||
|
import {ChartSaubDataOnline} from '../components/charts/ChartSaubDataOnline'
|
||||||
|
|
||||||
import {useParams} from 'react-router-dom'
|
import {useParams} from 'react-router-dom'
|
||||||
|
import {Subscribe} from '../services/signalr'
|
||||||
|
import {DataService} from '../services/api'
|
||||||
|
|
||||||
export default function Well(props){
|
export default function Well(props){
|
||||||
let { id } = useParams();
|
let { id } = useParams();
|
||||||
return(<div>Well id: {id}</div>)
|
const [saubData, setSaubData] = useState([])
|
||||||
|
|
||||||
|
const handleReceiveDataSaub = (data)=>{
|
||||||
|
setSaubData(pre => [...pre, ...data].slice(-1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect( ()=> {
|
||||||
|
DataService.get(id)
|
||||||
|
.then(handleReceiveDataSaub)
|
||||||
|
.catch(error=>console.error(error))
|
||||||
|
|
||||||
|
return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
|
||||||
|
},
|
||||||
|
[id]);
|
||||||
|
|
||||||
|
|
||||||
|
return(<div>
|
||||||
|
Well id: {id}; points count: {saubData.length}
|
||||||
|
<ChartSaubDataOnline/>
|
||||||
|
</div>)
|
||||||
}
|
}
|
@ -35,8 +35,8 @@ export default function Wells(props){
|
|||||||
let updateWellsList = async () => {
|
let updateWellsList = async () => {
|
||||||
setLoader(true)
|
setLoader(true)
|
||||||
try{
|
try{
|
||||||
|
var newWells = (await WellService.get()).map(w =>{return {key:w.id, ...w}})
|
||||||
setWells( await WellService.get())
|
setWells( newWells )
|
||||||
}
|
}
|
||||||
catch(e){
|
catch(e){
|
||||||
console.error(`${e.message}`);
|
console.error(`${e.message}`);
|
||||||
|
@ -1 +1 @@
|
|||||||
npx openapi -i http://localhost:5000/swagger/v1/swagger.json -o src/services/openapi
|
npx openapi -i http://localhost:5000/swagger/v1/swagger.json -o src/services/api
|
@ -5,8 +5,13 @@ export { ApiError } from './core/ApiError';
|
|||||||
export { OpenAPI } from './core/OpenAPI';
|
export { OpenAPI } from './core/OpenAPI';
|
||||||
|
|
||||||
export type { AuthDto } from './models/AuthDto';
|
export type { AuthDto } from './models/AuthDto';
|
||||||
|
export type { DataSaubBaseDto } from './models/DataSaubBaseDto';
|
||||||
|
export type { TelemetryDataDto } from './models/TelemetryDataDto';
|
||||||
|
export type { TelemetryInfoDto } from './models/TelemetryInfoDto';
|
||||||
export type { UserTokenDto } from './models/UserTokenDto';
|
export type { UserTokenDto } from './models/UserTokenDto';
|
||||||
export type { WellDto } from './models/WellDto';
|
export type { WellDto } from './models/WellDto';
|
||||||
|
|
||||||
export { AuthService } from './services/AuthService';
|
export { AuthService } from './services/AuthService';
|
||||||
|
export { DataService } from './services/DataService';
|
||||||
|
export { TelemetryService } from './services/TelemetryService';
|
||||||
export { WellService } from './services/WellService';
|
export { WellService } from './services/WellService';
|
||||||
|
32
src/services/api/models/DataSaubBaseDto.ts
Normal file
32
src/services/api/models/DataSaubBaseDto.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
export type DataSaubBaseDto = {
|
||||||
|
date?: string;
|
||||||
|
mode?: number | null;
|
||||||
|
wellDepth?: number | null;
|
||||||
|
bitDepth?: number | null;
|
||||||
|
blockHeight?: number | null;
|
||||||
|
blockSpeed?: number | null;
|
||||||
|
blockSpeedSp?: number | null;
|
||||||
|
pressure?: number | null;
|
||||||
|
pressureIdle?: number | null;
|
||||||
|
pressureSp?: number | null;
|
||||||
|
pressureDeltaLimitMax?: number | null;
|
||||||
|
axialLoad?: number | null;
|
||||||
|
axialLoadSp?: number | null;
|
||||||
|
axialLoadLimitMax?: number | null;
|
||||||
|
hookWeight?: number | null;
|
||||||
|
hookWeightIdle?: number | null;
|
||||||
|
hookWeightLimitMin?: number | null;
|
||||||
|
hookWeightLimitMax?: number | null;
|
||||||
|
rotorTorque?: number | null;
|
||||||
|
rotorTorqueIdle?: number | null;
|
||||||
|
rotorTorqueSp?: number | null;
|
||||||
|
rotorTorqueLimitMax?: number | null;
|
||||||
|
rotorSpeed?: number | null;
|
||||||
|
flow?: number | null;
|
||||||
|
flowIdle?: number | null;
|
||||||
|
flowDeltaLimitMax?: number | null;
|
||||||
|
}
|
12
src/services/api/models/TelemetryDataDto.ts
Normal file
12
src/services/api/models/TelemetryDataDto.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import type { DataSaubBaseDto } from './DataSaubBaseDto';
|
||||||
|
|
||||||
|
export type TelemetryDataDto = {
|
||||||
|
date?: string;
|
||||||
|
hmiVersion?: string | null;
|
||||||
|
userName?: string | null;
|
||||||
|
dataSaub?: Array<DataSaubBaseDto> | null;
|
||||||
|
}
|
9
src/services/api/models/TelemetryInfoDto.ts
Normal file
9
src/services/api/models/TelemetryInfoDto.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
export type TelemetryInfoDto = {
|
||||||
|
caption?: string | null;
|
||||||
|
cluster?: string | null;
|
||||||
|
deposit?: string | null;
|
||||||
|
}
|
@ -3,9 +3,9 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
export type WellDto = {
|
export type WellDto = {
|
||||||
id?: number;
|
|
||||||
caption?: string | null;
|
caption?: string | null;
|
||||||
cluster?: string | null;
|
cluster?: string | null;
|
||||||
deposit?: string | null;
|
deposit?: string | null;
|
||||||
|
id?: number;
|
||||||
lastData?: any;
|
lastData?: any;
|
||||||
}
|
}
|
25
src/services/api/services/DataService.ts
Normal file
25
src/services/api/services/DataService.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { DataSaubBaseDto } from '../models/DataSaubBaseDto';
|
||||||
|
import { request as __request } from '../core/request';
|
||||||
|
|
||||||
|
export class DataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает данные САУБ по скважине
|
||||||
|
* @param wellId
|
||||||
|
* @returns DataSaubBaseDto Success
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static async get(
|
||||||
|
wellId: number,
|
||||||
|
): Promise<Array<DataSaubBaseDto>> {
|
||||||
|
const result = await __request({
|
||||||
|
method: 'GET',
|
||||||
|
path: `/api/well/${wellId}/data`,
|
||||||
|
});
|
||||||
|
return result.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
src/services/api/services/TelemetryService.ts
Normal file
48
src/services/api/services/TelemetryService.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { TelemetryDataDto } from '../models/TelemetryDataDto';
|
||||||
|
import type { TelemetryInfoDto } from '../models/TelemetryInfoDto';
|
||||||
|
import { request as __request } from '../core/request';
|
||||||
|
|
||||||
|
export class TelemetryService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Принимает общую информацию по скважине
|
||||||
|
* @param uid Уникальный идентификатор отправителя
|
||||||
|
* @param requestBody нформация об отправителе
|
||||||
|
* @returns any Success
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static async info(
|
||||||
|
uid: string,
|
||||||
|
requestBody?: TelemetryInfoDto,
|
||||||
|
): Promise<any> {
|
||||||
|
const result = await __request({
|
||||||
|
method: 'POST',
|
||||||
|
path: `/api/telemetry/${uid}/info`,
|
||||||
|
body: requestBody,
|
||||||
|
});
|
||||||
|
return result.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Принимает данные от разных систем по скважине
|
||||||
|
* @param uid Уникальный идентификатор отправителя
|
||||||
|
* @param requestBody Данные
|
||||||
|
* @returns any Success
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static async data(
|
||||||
|
uid: string,
|
||||||
|
requestBody?: TelemetryDataDto,
|
||||||
|
): Promise<any> {
|
||||||
|
const result = await __request({
|
||||||
|
method: 'POST',
|
||||||
|
path: `/api/telemetry/${uid}/data`,
|
||||||
|
body: requestBody,
|
||||||
|
});
|
||||||
|
return result.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,7 +13,7 @@ export class WellService {
|
|||||||
public static async get(): Promise<Array<WellDto>> {
|
public static async get(): Promise<Array<WellDto>> {
|
||||||
const result = await __request({
|
const result = await __request({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `/api/Well`,
|
path: `/api/well`,
|
||||||
});
|
});
|
||||||
return result.body;
|
return result.body;
|
||||||
}
|
}
|
||||||
|
70
src/services/signalr/index.ts
Normal file
70
src/services/signalr/index.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';
|
||||||
|
|
||||||
|
// SignalR js api:
|
||||||
|
//https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest
|
||||||
|
|
||||||
|
const ConnectionOptions = {
|
||||||
|
accessTokenFactory: () => localStorage['token'],
|
||||||
|
//transport:1,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Connection = new HubConnectionBuilder()
|
||||||
|
.withUrl(`http://localhost:5000/hubs/telemetry`, ConnectionOptions)
|
||||||
|
.withAutomaticReconnect()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
const GetConnectionAsync = async ()=>{
|
||||||
|
if(Connection.state !== HubConnectionState.Connected)
|
||||||
|
await Connection.start()
|
||||||
|
|
||||||
|
if(Connection.state === HubConnectionState.Connected)
|
||||||
|
return Connection
|
||||||
|
else
|
||||||
|
throw new Error('Can`t connect to websocket')
|
||||||
|
}
|
||||||
|
|
||||||
|
type handlerFunction = (...args: any[]) => void;
|
||||||
|
|
||||||
|
type cleanFunction = (...args: any[]) => void;
|
||||||
|
|
||||||
|
/** Subscribe on some SignalR method (topic).
|
||||||
|
* @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]);
|
||||||
|
* @param {string} methodName name of the method
|
||||||
|
* @param {string} groupName name of the group
|
||||||
|
* @param {handlerFunction} handler fires when got new data by subscription
|
||||||
|
* @return {cleanFunction} unsubscribe function for useEffect cleanup.
|
||||||
|
*/
|
||||||
|
const Subscribe = (
|
||||||
|
methodName: string,
|
||||||
|
groupName: string = '',
|
||||||
|
handler: handlerFunction ):cleanFunction=>{
|
||||||
|
|
||||||
|
GetConnectionAsync().then(async connection => {
|
||||||
|
if(groupName)
|
||||||
|
await connection.send('AddToGroup', groupName)
|
||||||
|
connection.on(methodName, handler)
|
||||||
|
})
|
||||||
|
|
||||||
|
if(groupName)
|
||||||
|
return () => {
|
||||||
|
Connection.send('RemoveFromGroup', groupName)
|
||||||
|
.finally(()=>Connection.off(methodName))
|
||||||
|
}
|
||||||
|
return () => Connection.off(methodName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Invokes some SignalR method.
|
||||||
|
* @param {string} methodName name of the method
|
||||||
|
* @param {any[]} args methods arguments
|
||||||
|
* @return {Promise<void>} Promise
|
||||||
|
*/
|
||||||
|
const InvokeAsync = async (methodName:string, ...args:any[]) => {
|
||||||
|
await GetConnectionAsync()
|
||||||
|
await Connection.send(methodName, ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Subscribe,
|
||||||
|
InvokeAsync,
|
||||||
|
GetConnectionAsync,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user