@yuants/protocol
Advanced tools
Comparing version 0.22.1 to 0.23.0
@@ -314,2 +314,6 @@ /** | ||
/** | ||
* A flag to indicate whether the terminal enables WebRTC messaging tunnel | ||
*/ | ||
enable_WebRTC?: boolean; | ||
/** | ||
* Status text | ||
@@ -475,3 +479,6 @@ * 状态文字 | ||
constructor(host_url: string, terminalInfo: ITerminalInfo, connection?: IConnection<ITerminalMessage>); | ||
private _mapTerminalIdToPeer; | ||
private _setupTunnel; | ||
private _setupPeer; | ||
private _setupWebRTCTunnel; | ||
private _setupTerminalInfoStuff; | ||
@@ -478,0 +485,0 @@ private _subscriptions; |
@@ -5,5 +5,6 @@ import { UUID, formatTime } from '@yuants/data-model'; | ||
import { isNode } from 'browser-or-node'; | ||
import { EMPTY, Observable, ReplaySubject, Subject, catchError, debounceTime, defer, distinctUntilChanged, filter, first, firstValueFrom, from, groupBy, interval, map, mergeAll, mergeMap, of, repeat, retry, share, shareReplay, switchMap, takeWhile, tap, timeout, timer, toArray, } from 'rxjs'; | ||
import { EMPTY, Observable, ReplaySubject, Subject, catchError, debounceTime, defer, distinctUntilChanged, exhaustMap, filter, first, firstValueFrom, from, groupBy, interval, map, mergeAll, mergeMap, of, repeat, retry, share, shareReplay, switchMap, takeWhile, tap, timeout, timer, toArray, withLatestFrom, } from 'rxjs'; | ||
import { createConnectionJson } from './create-connection'; | ||
import { PromRegistry } from './services/metrics'; | ||
import { getSimplePeerInstance } from './webrtc'; | ||
const TerminalReceiveMassageTotal = PromRegistry.create('counter', 'terminal_receive_message_total'); | ||
@@ -29,2 +30,3 @@ const TerminalTransmittedMessageTotal = PromRegistry.create('counter', 'terminal_transmitted_message_total'); | ||
this._terminalInfoUpdated$ = new Subject(); | ||
this._mapTerminalIdToPeer = {}; | ||
this._subscriptions = []; | ||
@@ -80,16 +82,2 @@ this._input$ = new Subject(); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (msg.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.LOG_LEVEL) === 'DEBUG') { | ||
@@ -101,16 +89,2 @@ console.debug(formatTime(Date.now()), 'Terminal', 'RX', msg.trace_id, msg.method, (_d = (_c = msg.res) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : '', (_f = (_e = msg.res) === null || _e === void 0 ? void 0 : _e.message) !== null && _f !== void 0 ? _f : ''); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (msg.method) { | ||
TerminalTransmittedMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalTransmittedChannelMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.LOG_LEVEL) === 'DEBUG') { | ||
@@ -393,4 +367,23 @@ console.debug(formatTime(Date.now()), 'Terminal', 'TX', msg.trace_id, msg.method, (_d = (_c = msg.res) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : '', (_f = (_e = msg.res) === null || _e === void 0 ? void 0 : _e.message) !== null && _f !== void 0 ? _f : ''); | ||
this._subscriptions.push(from(this._conn.input$).subscribe((msg) => { | ||
if (msg.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: 'WS', | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: 'WS', | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
this._input$.next(msg); | ||
})); | ||
if (this.terminalInfo.enable_WebRTC) { | ||
this._setupWebRTCTunnel(); | ||
} | ||
this._subscriptions.push(this._output$.subscribe((msg) => { | ||
@@ -403,5 +396,155 @@ // Local Loop Back Tunnel | ||
} | ||
// WebRTC Tunnel | ||
const peerInfo = this._mapTerminalIdToPeer[msg.target_terminal_id]; | ||
if (msg.method) { | ||
TerminalTransmittedMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: peerInfo !== undefined && peerInfo.peer.connected ? 'WebRTC' : 'WS', | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalTransmittedChannelMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: peerInfo !== undefined && peerInfo.peer.connected ? 'WebRTC' : 'WS', | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (peerInfo && peerInfo.peer.connected) { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'sent', JSON.stringify(msg)); | ||
setTimeout(() => peerInfo.peer.send(JSON.stringify(msg))); | ||
return; | ||
} | ||
this._conn.output$.next(msg); | ||
})); | ||
} | ||
_setupPeer(config) { | ||
const { session_id, direction, remote_terminal_id, onSignal, onDestroy } = config; | ||
const peer = getSimplePeerInstance({ | ||
initiator: direction === 'Active', | ||
channelName: direction === 'Active' | ||
? `${this.terminal_id}/${remote_terminal_id}` | ||
: `${remote_terminal_id}/${this.terminal_id}`, | ||
}); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = { | ||
session_id, | ||
peer, | ||
}; | ||
peer.on('signal', (data) => { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', direction, 'signal', session_id, remote_terminal_id, data); | ||
onSignal(data); | ||
}); | ||
peer.on('data', (data) => { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', direction, 'data', session_id, remote_terminal_id, data.toString()); | ||
if (data.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: this.terminal_id, | ||
source_terminal_id: remote_terminal_id, | ||
tunnel: 'WebRTC', | ||
method: data.method, | ||
}); | ||
} | ||
if (data.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: this.terminal_id, | ||
source_terminal_id: remote_terminal_id, | ||
tunnel: 'WebRTC', | ||
channel_id: data.channel_id, | ||
}); | ||
} | ||
this._input$.next(JSON.parse(data.toString())); | ||
}); | ||
peer.on('connect', () => { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', direction, 'connected', session_id, remote_terminal_id); | ||
}); | ||
peer.on('close', () => { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', direction, 'closed', session_id, remote_terminal_id); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = undefined; | ||
onDestroy(); | ||
}); | ||
peer.on('error', (err) => { | ||
console.error(formatTime(Date.now()), 'Terminal', 'WebRTC', direction, 'error', session_id, remote_terminal_id, err); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = undefined; | ||
onDestroy(); | ||
}); | ||
return peer; | ||
} | ||
_setupWebRTCTunnel() { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Setup'); | ||
this.provideService('WebRTC/Offer', {}, async (msg) => { | ||
const { session_id, offer } = msg.req; | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'Offer Received', session_id, msg.source_terminal_id, msg.req); | ||
const peerInfo = this._mapTerminalIdToPeer[msg.source_terminal_id]; | ||
if (peerInfo !== undefined && peerInfo.session_id === session_id) { | ||
// same Session, check if connection is established | ||
if (!peerInfo.peer.connected) { | ||
peerInfo.peer.signal(offer); | ||
} | ||
return { res: { code: 200, message: 'OK' } }; | ||
} | ||
if (peerInfo !== undefined && peerInfo.session_id !== session_id) { | ||
// NOTE: here are the conflict case, to resolve the conflict, we should give up the upper terminal_id' peer | ||
if (msg.source_terminal_id < msg.target_terminal_id) { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'GiveUp', session_id, msg.source_terminal_id, msg.req); | ||
peerInfo.peer.destroy(); | ||
this._mapTerminalIdToPeer[msg.source_terminal_id] = undefined; | ||
} | ||
else { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'Conflict', session_id, msg.source_terminal_id, msg.req); | ||
return { res: { code: 409, message: 'Conflict' } }; | ||
} | ||
} | ||
const peer = this._setupPeer({ | ||
session_id, | ||
direction: 'Passive', | ||
remote_terminal_id: msg.source_terminal_id, | ||
onSignal: (data) => { | ||
from(this.request('WebRTC/Answer', msg.source_terminal_id, { session_id, answer: data })).subscribe(); | ||
}, | ||
onDestroy: () => { }, | ||
}); | ||
peer.signal(offer); | ||
return { res: { code: 200, message: 'OK' } }; | ||
}); | ||
this.provideService('WebRTC/Answer', {}, async (msg) => { | ||
const { session_id, answer } = msg.req; | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Active', 'Answer Received', session_id, msg.source_terminal_id, msg.req); | ||
const peerInfo = this._mapTerminalIdToPeer[msg.source_terminal_id]; | ||
if (peerInfo === undefined || peerInfo.session_id !== session_id) { | ||
return { res: { code: 404, message: 'Not Found' } }; | ||
} | ||
peerInfo.peer.signal(answer); | ||
return { res: { code: 200, message: 'OK' } }; | ||
}); | ||
this._subscriptions.push(this._output$ | ||
.pipe(map((msg) => msg.target_terminal_id), filter((x) => x !== this.terminal_id), groupBy((x) => x), mergeMap((group) => group.pipe(withLatestFrom(this._terminalInfos$), exhaustMap(([target_terminal_id, terminal_infos]) => new Observable((observer) => { | ||
if (!terminal_infos.find((x) => x.terminal_id === target_terminal_id && x.enable_WebRTC)) { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Active', 'not enabled for', target_terminal_id); | ||
observer.complete(); | ||
return; | ||
} | ||
const peerInfo = this._mapTerminalIdToPeer[target_terminal_id]; | ||
if (peerInfo !== undefined) { | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Active', 'already connected', peerInfo.session_id, target_terminal_id); | ||
// NOTE: we don't complete the observer here to block the next active connection requests | ||
return; | ||
} | ||
const session_id = UUID(); | ||
console.info(formatTime(Date.now()), 'Terminal', 'WebRTC', 'Active', 'connecting', session_id, target_terminal_id); | ||
const _ = this._setupPeer({ | ||
session_id, | ||
direction: 'Active', | ||
remote_terminal_id: target_terminal_id, | ||
onSignal: (data) => { | ||
from(this.request('WebRTC/Offer', target_terminal_id, { session_id, offer: data })).subscribe(); | ||
}, | ||
onDestroy: () => { | ||
observer.complete(); | ||
}, | ||
}); | ||
}))))) | ||
.subscribe()); | ||
} | ||
_setupTerminalInfoStuff() { | ||
@@ -408,0 +551,0 @@ // Periodically update the whole terminal list |
@@ -69,2 +69,6 @@ import { JSONSchema7 } from 'json-schema'; | ||
/** | ||
* A flag to indicate whether the terminal enables WebRTC messaging tunnel | ||
*/ | ||
enable_WebRTC?: boolean; | ||
/** | ||
* Status text | ||
@@ -71,0 +75,0 @@ * 状态文字 |
@@ -37,3 +37,6 @@ import { NativeSubject } from '@yuants/utils'; | ||
constructor(host_url: string, terminalInfo: ITerminalInfo, connection?: IConnection<ITerminalMessage>); | ||
private _mapTerminalIdToPeer; | ||
private _setupTunnel; | ||
private _setupPeer; | ||
private _setupWebRTCTunnel; | ||
private _setupTerminalInfoStuff; | ||
@@ -40,0 +43,0 @@ private _subscriptions; |
@@ -14,2 +14,3 @@ "use strict"; | ||
const metrics_1 = require("./services/metrics"); | ||
const webrtc_1 = require("./webrtc"); | ||
const TerminalReceiveMassageTotal = metrics_1.PromRegistry.create('counter', 'terminal_receive_message_total'); | ||
@@ -35,2 +36,3 @@ const TerminalTransmittedMessageTotal = metrics_1.PromRegistry.create('counter', 'terminal_transmitted_message_total'); | ||
this._terminalInfoUpdated$ = new rxjs_1.Subject(); | ||
this._mapTerminalIdToPeer = {}; | ||
this._subscriptions = []; | ||
@@ -86,16 +88,2 @@ this._input$ = new rxjs_1.Subject(); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (msg.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.LOG_LEVEL) === 'DEBUG') { | ||
@@ -107,16 +95,2 @@ console.debug((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'RX', msg.trace_id, msg.method, (_d = (_c = msg.res) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : '', (_f = (_e = msg.res) === null || _e === void 0 ? void 0 : _e.message) !== null && _f !== void 0 ? _f : ''); | ||
var _a, _b, _c, _d, _e, _f; | ||
if (msg.method) { | ||
TerminalTransmittedMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalTransmittedChannelMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.LOG_LEVEL) === 'DEBUG') { | ||
@@ -399,4 +373,23 @@ console.debug((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'TX', msg.trace_id, msg.method, (_d = (_c = msg.res) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : '', (_f = (_e = msg.res) === null || _e === void 0 ? void 0 : _e.message) !== null && _f !== void 0 ? _f : ''); | ||
this._subscriptions.push((0, rxjs_1.from)(this._conn.input$).subscribe((msg) => { | ||
if (msg.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: 'WS', | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: 'WS', | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
this._input$.next(msg); | ||
})); | ||
if (this.terminalInfo.enable_WebRTC) { | ||
this._setupWebRTCTunnel(); | ||
} | ||
this._subscriptions.push(this._output$.subscribe((msg) => { | ||
@@ -409,5 +402,155 @@ // Local Loop Back Tunnel | ||
} | ||
// WebRTC Tunnel | ||
const peerInfo = this._mapTerminalIdToPeer[msg.target_terminal_id]; | ||
if (msg.method) { | ||
TerminalTransmittedMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: peerInfo !== undefined && peerInfo.peer.connected ? 'WebRTC' : 'WS', | ||
method: msg.method, | ||
}); | ||
} | ||
if (msg.channel_id) { | ||
TerminalTransmittedChannelMessageTotal.inc({ | ||
target_terminal_id: msg.target_terminal_id, | ||
source_terminal_id: msg.source_terminal_id, | ||
tunnel: peerInfo !== undefined && peerInfo.peer.connected ? 'WebRTC' : 'WS', | ||
channel_id: msg.channel_id, | ||
}); | ||
} | ||
if (peerInfo && peerInfo.peer.connected) { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'sent', JSON.stringify(msg)); | ||
setTimeout(() => peerInfo.peer.send(JSON.stringify(msg))); | ||
return; | ||
} | ||
this._conn.output$.next(msg); | ||
})); | ||
} | ||
_setupPeer(config) { | ||
const { session_id, direction, remote_terminal_id, onSignal, onDestroy } = config; | ||
const peer = (0, webrtc_1.getSimplePeerInstance)({ | ||
initiator: direction === 'Active', | ||
channelName: direction === 'Active' | ||
? `${this.terminal_id}/${remote_terminal_id}` | ||
: `${remote_terminal_id}/${this.terminal_id}`, | ||
}); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = { | ||
session_id, | ||
peer, | ||
}; | ||
peer.on('signal', (data) => { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', direction, 'signal', session_id, remote_terminal_id, data); | ||
onSignal(data); | ||
}); | ||
peer.on('data', (data) => { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', direction, 'data', session_id, remote_terminal_id, data.toString()); | ||
if (data.method) { | ||
TerminalReceiveMassageTotal.inc({ | ||
target_terminal_id: this.terminal_id, | ||
source_terminal_id: remote_terminal_id, | ||
tunnel: 'WebRTC', | ||
method: data.method, | ||
}); | ||
} | ||
if (data.channel_id) { | ||
TerminalReceiveChannelMassageTotal.inc({ | ||
target_terminal_id: this.terminal_id, | ||
source_terminal_id: remote_terminal_id, | ||
tunnel: 'WebRTC', | ||
channel_id: data.channel_id, | ||
}); | ||
} | ||
this._input$.next(JSON.parse(data.toString())); | ||
}); | ||
peer.on('connect', () => { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', direction, 'connected', session_id, remote_terminal_id); | ||
}); | ||
peer.on('close', () => { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', direction, 'closed', session_id, remote_terminal_id); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = undefined; | ||
onDestroy(); | ||
}); | ||
peer.on('error', (err) => { | ||
console.error((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', direction, 'error', session_id, remote_terminal_id, err); | ||
this._mapTerminalIdToPeer[remote_terminal_id] = undefined; | ||
onDestroy(); | ||
}); | ||
return peer; | ||
} | ||
_setupWebRTCTunnel() { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Setup'); | ||
this.provideService('WebRTC/Offer', {}, async (msg) => { | ||
const { session_id, offer } = msg.req; | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'Offer Received', session_id, msg.source_terminal_id, msg.req); | ||
const peerInfo = this._mapTerminalIdToPeer[msg.source_terminal_id]; | ||
if (peerInfo !== undefined && peerInfo.session_id === session_id) { | ||
// same Session, check if connection is established | ||
if (!peerInfo.peer.connected) { | ||
peerInfo.peer.signal(offer); | ||
} | ||
return { res: { code: 200, message: 'OK' } }; | ||
} | ||
if (peerInfo !== undefined && peerInfo.session_id !== session_id) { | ||
// NOTE: here are the conflict case, to resolve the conflict, we should give up the upper terminal_id' peer | ||
if (msg.source_terminal_id < msg.target_terminal_id) { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'GiveUp', session_id, msg.source_terminal_id, msg.req); | ||
peerInfo.peer.destroy(); | ||
this._mapTerminalIdToPeer[msg.source_terminal_id] = undefined; | ||
} | ||
else { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Passive', 'Conflict', session_id, msg.source_terminal_id, msg.req); | ||
return { res: { code: 409, message: 'Conflict' } }; | ||
} | ||
} | ||
const peer = this._setupPeer({ | ||
session_id, | ||
direction: 'Passive', | ||
remote_terminal_id: msg.source_terminal_id, | ||
onSignal: (data) => { | ||
(0, rxjs_1.from)(this.request('WebRTC/Answer', msg.source_terminal_id, { session_id, answer: data })).subscribe(); | ||
}, | ||
onDestroy: () => { }, | ||
}); | ||
peer.signal(offer); | ||
return { res: { code: 200, message: 'OK' } }; | ||
}); | ||
this.provideService('WebRTC/Answer', {}, async (msg) => { | ||
const { session_id, answer } = msg.req; | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Active', 'Answer Received', session_id, msg.source_terminal_id, msg.req); | ||
const peerInfo = this._mapTerminalIdToPeer[msg.source_terminal_id]; | ||
if (peerInfo === undefined || peerInfo.session_id !== session_id) { | ||
return { res: { code: 404, message: 'Not Found' } }; | ||
} | ||
peerInfo.peer.signal(answer); | ||
return { res: { code: 200, message: 'OK' } }; | ||
}); | ||
this._subscriptions.push(this._output$ | ||
.pipe((0, rxjs_1.map)((msg) => msg.target_terminal_id), (0, rxjs_1.filter)((x) => x !== this.terminal_id), (0, rxjs_1.groupBy)((x) => x), (0, rxjs_1.mergeMap)((group) => group.pipe((0, rxjs_1.withLatestFrom)(this._terminalInfos$), (0, rxjs_1.exhaustMap)(([target_terminal_id, terminal_infos]) => new rxjs_1.Observable((observer) => { | ||
if (!terminal_infos.find((x) => x.terminal_id === target_terminal_id && x.enable_WebRTC)) { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Active', 'not enabled for', target_terminal_id); | ||
observer.complete(); | ||
return; | ||
} | ||
const peerInfo = this._mapTerminalIdToPeer[target_terminal_id]; | ||
if (peerInfo !== undefined) { | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Active', 'already connected', peerInfo.session_id, target_terminal_id); | ||
// NOTE: we don't complete the observer here to block the next active connection requests | ||
return; | ||
} | ||
const session_id = (0, data_model_1.UUID)(); | ||
console.info((0, data_model_1.formatTime)(Date.now()), 'Terminal', 'WebRTC', 'Active', 'connecting', session_id, target_terminal_id); | ||
const _ = this._setupPeer({ | ||
session_id, | ||
direction: 'Active', | ||
remote_terminal_id: target_terminal_id, | ||
onSignal: (data) => { | ||
(0, rxjs_1.from)(this.request('WebRTC/Offer', target_terminal_id, { session_id, offer: data })).subscribe(); | ||
}, | ||
onDestroy: () => { | ||
observer.complete(); | ||
}, | ||
}); | ||
}))))) | ||
.subscribe()); | ||
} | ||
_setupTerminalInfoStuff() { | ||
@@ -414,0 +557,0 @@ // Periodically update the whole terminal list |
{ | ||
"name": "@yuants/protocol", | ||
"version": "0.22.1", | ||
"version": "0.23.0", | ||
"main": "lib/index.js", | ||
@@ -20,3 +20,5 @@ "module": "dist/index.js", | ||
"ws": "~8.11.0", | ||
"@yuants/prometheus-client": "0.0.4" | ||
"@yuants/prometheus-client": "0.0.4", | ||
"simple-peer": "~9.11.1", | ||
"@roamhq/wrtc": "~0.8.0" | ||
}, | ||
@@ -32,3 +34,4 @@ "devDependencies": { | ||
"@yuants/tool-kit": "0.1.4", | ||
"typescript": "~4.7.4" | ||
"typescript": "~4.7.4", | ||
"@types/simple-peer": "~9.11.8" | ||
}, | ||
@@ -35,0 +38,0 @@ "publishConfig": { |
{ | ||
"libraries/protocol/CHANGELOG.json": "e205d0b1872987852ab4871ed41b78f34af6ade1", | ||
"libraries/protocol/CHANGELOG.md": "e7efa70f41bda0b9b70ff47943a9542ddb4ffdc2", | ||
"libraries/protocol/CHANGELOG.json": "312595783c95bff4538c5d7b55b59a36049e1763", | ||
"libraries/protocol/CHANGELOG.md": "072b34fe8fc0287a8afdfcaa4334f92ad199835c", | ||
"libraries/protocol/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c", | ||
@@ -8,7 +8,7 @@ "libraries/protocol/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd", | ||
"libraries/protocol/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348", | ||
"libraries/protocol/etc/protocol.api.md": "14c74b215e1d55d4a11ce0311e2c044c6cbcd4a2", | ||
"libraries/protocol/package.json": "8ade7df9b71a8f9fc643b73a839772cdeef65820", | ||
"libraries/protocol/etc/protocol.api.md": "2275d7a334a65f54530dd3d79109c947f45553b0", | ||
"libraries/protocol/package.json": "5ac5e5cfb155c63b23f3a5260f150647b3ae0a70", | ||
"libraries/protocol/src/create-connection.ts": "4fe9f0e005d62910c1bc76abe31df79e4ab64f1e", | ||
"libraries/protocol/src/index.ts": "d4d17468883fe9a097862e3a24e6836898ee610b", | ||
"libraries/protocol/src/model.ts": "2d6b93c7efc1ae36c6380b954d032c7d686ead08", | ||
"libraries/protocol/src/model.ts": "5bcce454e37cfb9142fd42b609565d6f7dba8454", | ||
"libraries/protocol/src/services/data-record.ts": "98db9004bca18f4c4915cba592c520b28503f63a", | ||
@@ -23,3 +23,3 @@ "libraries/protocol/src/services/index.ts": "8a2c4218e3e7bee5a3c9a2ab51e113d4ce852bee", | ||
"libraries/protocol/src/terminal.test.ts": "a88d7681da88e37ded88571fb5374a9e94a4d428", | ||
"libraries/protocol/src/terminal.ts": "0b777207a9607e9429d801832843bb617c2443db", | ||
"libraries/protocol/src/terminal.ts": "fa8713670cd76a4b244c9a4cf0f694e3b063a00f", | ||
"libraries/protocol/src/utils/DataRecord.ts": "5a942dea5beee36c7f823c8aa70edad6e72ec9ef", | ||
@@ -36,4 +36,5 @@ "libraries/protocol/src/utils/Order.ts": "7b2b6b2659a8953aa95def726b1d02cd4fa4654c", | ||
"libraries/protocol/src/utils/provideTicks.ts": "52cf968cf44a0a00e98684795e26ff577ef6bb7b", | ||
"libraries/protocol/src/webrtc.ts": "b0d595e1c21e102ab39698a62adf1cd7d914f609", | ||
"libraries/protocol/tsconfig.json": "b0970ddc83063731c79d217a52d27b50dfbbc0c8", | ||
"libraries/protocol/.rush/temp/shrinkwrap-deps.json": "b3b3c41ca7a6a410320b482a3f7a6cf9321b589d", | ||
"libraries/protocol/.rush/temp/shrinkwrap-deps.json": "1d3656ca45a24cee559fe7ba5c930c9a1bf58b16", | ||
"libraries/data-model/temp/package-deps.json": "a1d18b421f39bb45d191d84827bb11179f9ea7fc", | ||
@@ -40,0 +41,0 @@ "libraries/utils/temp/package-deps.json": "846e11c0f180c157ee1afcbabf1f0fdded8f8ff9", |
@@ -67,2 +67,3 @@ ## API Report File for "@yuants/protocol" | ||
created_at?: number; | ||
enable_WebRTC?: boolean; | ||
name?: string; | ||
@@ -69,0 +70,0 @@ serviceInfo?: Record<string, { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
591656
156
7286
11
10
+ Added@roamhq/wrtc@~0.8.0
+ Addedsimple-peer@~9.11.1
+ Added@roamhq/wrtc@0.8.0(transitive)
+ Added@roamhq/wrtc-darwin-arm64@0.8.0(transitive)
+ Added@roamhq/wrtc-darwin-x64@0.8.0(transitive)
+ Added@roamhq/wrtc-linux-arm64@0.8.1(transitive)
+ Added@roamhq/wrtc-linux-x64@0.8.1(transitive)
+ Added@roamhq/wrtc-win32-x64@0.8.0(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbuffer@6.0.3(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addeddomexception@4.0.0(transitive)
+ Addederr-code@3.0.1(transitive)
+ Addedget-browser-rtc@1.1.0(transitive)
+ Addedieee754@1.2.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedms@2.1.3(transitive)
+ Addedqueue-microtask@1.2.3(transitive)
+ Addedrandombytes@2.1.0(transitive)
+ Addedreadable-stream@3.6.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsimple-peer@9.11.1(transitive)
+ Addedstring_decoder@1.3.0(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwebidl-conversions@7.0.0(transitive)