can make relay connection now
This commit is contained in:
parent
85ec94e36c
commit
28c0967690
100
src/client.ts
Normal file
100
src/client.ts
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import Websock from "./websock";
|
||||||
|
import * as message from "./message.js";
|
||||||
|
import * as rendezvous from "./rendezvous.js";
|
||||||
|
import { loadVp9, loadOpus } from "./codec";
|
||||||
|
|
||||||
|
const URI = "ws://207.148.17.15";
|
||||||
|
const PORT = 21118;
|
||||||
|
const licenceKey = "";
|
||||||
|
|
||||||
|
loadVp9();
|
||||||
|
loadOpus();
|
||||||
|
|
||||||
|
export default class Client {
|
||||||
|
_msgs: any[];
|
||||||
|
_ws: Websock | undefined;
|
||||||
|
_interval: any;
|
||||||
|
_id: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._msgs = [];
|
||||||
|
this._id = '';
|
||||||
|
this._interval = setInterval(() => {
|
||||||
|
while (this._msgs.length) {
|
||||||
|
this._ws?.sendMessage(this._msgs[0]);
|
||||||
|
this._msgs.splice(0, 1);
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
clearInterval(this._interval);
|
||||||
|
this._ws?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
async connect(id: string) {
|
||||||
|
const ws = new Websock(URI + ":" + PORT);
|
||||||
|
this._ws = ws;
|
||||||
|
this._id = id;
|
||||||
|
await ws.open();
|
||||||
|
const connType = rendezvous.ConnType.DEFAULT_CONN;
|
||||||
|
const natType = rendezvous.NatType.SYMMETRIC;
|
||||||
|
const punchHoleRequest = rendezvous.PunchHoleRequest.fromJSON({
|
||||||
|
id,
|
||||||
|
licenceKey,
|
||||||
|
connType,
|
||||||
|
natType,
|
||||||
|
});
|
||||||
|
ws.sendRendezvous({ punchHoleRequest });
|
||||||
|
const msg = ws.parseRendezvous(await ws.next());
|
||||||
|
const phr = msg.punchHoleResponse;
|
||||||
|
const rr = msg.relayResponse;
|
||||||
|
if (phr) {
|
||||||
|
if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNKNOWN) {
|
||||||
|
switch (phr?.failure) {
|
||||||
|
case rendezvous.PunchHoleResponse_Failure.ID_NOT_EXIST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
} else if (rr) {
|
||||||
|
await this.connectRelay(rr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async connectRelay(rr: rendezvous.RelayResponse) {
|
||||||
|
const pk = rr.pk;
|
||||||
|
let uri = rr.relayServer;
|
||||||
|
if (uri.indexOf(':') > 0) {
|
||||||
|
const tmp = uri.split(':');
|
||||||
|
const port = parseInt(tmp[1]);
|
||||||
|
uri = tmp[0] + ':' + (port + 2);
|
||||||
|
} else {
|
||||||
|
uri += ':' + (PORT + 1);
|
||||||
|
}
|
||||||
|
const uuid = rr.uuid;
|
||||||
|
const ws = new Websock('ws://' + uri);
|
||||||
|
await ws.open();
|
||||||
|
console.log('Connected to relay server')
|
||||||
|
this._ws = ws;
|
||||||
|
const requestRelay = rendezvous.RequestRelay.fromJSON({
|
||||||
|
licenceKey,
|
||||||
|
uuid,
|
||||||
|
});
|
||||||
|
ws.sendRendezvous({ requestRelay });
|
||||||
|
await this.secure(pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
async secure(pk: Uint8Array | undefined) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testDelay() {
|
||||||
|
const ws = new Websock(URI + ":" + PORT);
|
||||||
|
await ws.open();
|
||||||
|
console.log(ws.latency());
|
||||||
|
}
|
||||||
|
|
||||||
|
await testDelay();
|
||||||
|
await new Client().connect("124931507");
|
88
src/codec.js
88
src/codec.js
@ -2,61 +2,61 @@
|
|||||||
// dev: copy decoder files from node/ogv/dist/* to project dir
|
// dev: copy decoder files from node/ogv/dist/* to project dir
|
||||||
// dist: .... to dist
|
// dist: .... to dist
|
||||||
/*
|
/*
|
||||||
OGVDemuxerOggW: 'ogv-demuxer-ogg-wasm.js',
|
OGVDemuxerOggW: 'ogv-demuxer-ogg-wasm.js',
|
||||||
OGVDemuxerWebMW: 'ogv-demuxer-webm-wasm.js',
|
OGVDemuxerWebMW: 'ogv-demuxer-webm-wasm.js',
|
||||||
OGVDecoderAudioOpusW: 'ogv-decoder-audio-opus-wasm.js',
|
OGVDecoderAudioOpusW: 'ogv-decoder-audio-opus-wasm.js',
|
||||||
OGVDecoderAudioVorbisW: 'ogv-decoder-audio-vorbis-wasm.js',
|
OGVDecoderAudioVorbisW: 'ogv-decoder-audio-vorbis-wasm.js',
|
||||||
OGVDecoderVideoTheoraW: 'ogv-decoder-video-theora-wasm.js',
|
OGVDecoderVideoTheoraW: 'ogv-decoder-video-theora-wasm.js',
|
||||||
OGVDecoderVideoVP8W: 'ogv-decoder-video-vp8-wasm.js',
|
OGVDecoderVideoVP8W: 'ogv-decoder-video-vp8-wasm.js',
|
||||||
OGVDecoderVideoVP8MTW: 'ogv-decoder-video-vp8-mt-wasm.js',
|
OGVDecoderVideoVP8MTW: 'ogv-decoder-video-vp8-mt-wasm.js',
|
||||||
OGVDecoderVideoVP9W: 'ogv-decoder-video-vp9-wasm.js',
|
OGVDecoderVideoVP9W: 'ogv-decoder-video-vp9-wasm.js',
|
||||||
OGVDecoderVideoVP9SIMDW: 'ogv-decoder-video-vp9-simd-wasm.js',
|
OGVDecoderVideoVP9SIMDW: 'ogv-decoder-video-vp9-simd-wasm.js',
|
||||||
OGVDecoderVideoVP9MTW: 'ogv-decoder-video-vp9-mt-wasm.js',
|
OGVDecoderVideoVP9MTW: 'ogv-decoder-video-vp9-mt-wasm.js',
|
||||||
OGVDecoderVideoVP9SIMDMTW: 'ogv-decoder-video-vp9-simd-mt-wasm.js',
|
OGVDecoderVideoVP9SIMDMTW: 'ogv-decoder-video-vp9-simd-mt-wasm.js',
|
||||||
OGVDecoderVideoAV1W: 'ogv-decoder-video-av1-wasm.js',
|
OGVDecoderVideoAV1W: 'ogv-decoder-video-av1-wasm.js',
|
||||||
OGVDecoderVideoAV1SIMDW: 'ogv-decoder-video-av1-simd-wasm.js',
|
OGVDecoderVideoAV1SIMDW: 'ogv-decoder-video-av1-simd-wasm.js',
|
||||||
OGVDecoderVideoAV1MTW: 'ogv-decoder-video-av1-mt-wasm.js',
|
OGVDecoderVideoAV1MTW: 'ogv-decoder-video-av1-mt-wasm.js',
|
||||||
OGVDecoderVideoAV1SIMDMTW: 'ogv-decoder-video-av1-simd-mt-wasm.js',
|
OGVDecoderVideoAV1SIMDMTW: 'ogv-decoder-video-av1-simd-mt-wasm.js',
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function loadVp9() {
|
export function loadVp9() {
|
||||||
window.OGVLoader.loadClass(
|
window.OGVLoader.loadClass(
|
||||||
"OGVDecoderVideoVP9W",
|
"OGVDecoderVideoVP9W",
|
||||||
(videoCodecClass) => {
|
(videoCodecClass) => {
|
||||||
videoCodecClass().then((decoder) => {
|
videoCodecClass().then((decoder) => {
|
||||||
decoder.init(() => {
|
decoder.init(() => {
|
||||||
onVp9Ready(decoder)
|
onVp9Ready(decoder)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ worker: true }
|
{ worker: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadOpus() {
|
export function loadOpus() {
|
||||||
window.OGVLoader.loadClass(
|
window.OGVLoader.loadClass(
|
||||||
"OGVDecoderAudioOpusW",
|
"OGVDecoderAudioOpusW",
|
||||||
(audioCodecClass) => {
|
(audioCodecClass) => {
|
||||||
audioCodecClass().then((decoder) => {
|
audioCodecClass().then((decoder) => {
|
||||||
decoder.init(() => {
|
decoder.init(() => {
|
||||||
onOpusReady(decoder)
|
onOpusReady(decoder)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ worker: true }
|
{ worker: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onVp9Ready(decoder) {
|
async function onVp9Ready(decoder) {
|
||||||
console.log("Vp9 decoder ready");
|
console.log("Vp9 decoder ready");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
decoder.processFrame(buffer, () => {
|
decoder.processFrame(buffer, () => {
|
||||||
player.drawFrame(decoder.frameBuffer)
|
player.drawFrame(decoder.frameBuffer)
|
||||||
})
|
})
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onOpusReady(decoder) {
|
async function onOpusReady(decoder) {
|
||||||
console.log("Opus decoder ready");
|
console.log("Opus decoder ready");
|
||||||
}
|
}
|
@ -1,9 +1,5 @@
|
|||||||
import './style.css';
|
import './style.css';
|
||||||
import { loadVp9, loadOpus } from "./codec";
|
import "./client";
|
||||||
import './websock';
|
|
||||||
|
|
||||||
loadVp9();
|
|
||||||
loadOpus();
|
|
||||||
|
|
||||||
const app = document.querySelector<HTMLDivElement>('#app')!
|
const app = document.querySelector<HTMLDivElement>('#app')!
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ export default class Websock {
|
|||||||
_eventHandlers: { [key in Keys]: Function };
|
_eventHandlers: { [key in Keys]: Function };
|
||||||
_buf: Uint8Array[];
|
_buf: Uint8Array[];
|
||||||
_status: any;
|
_status: any;
|
||||||
|
_latency: number;
|
||||||
|
|
||||||
constructor(uri: string) {
|
constructor(uri: string) {
|
||||||
this._eventHandlers = {
|
this._eventHandlers = {
|
||||||
@ -22,6 +23,11 @@ export default class Websock {
|
|||||||
this._websocket = new WebSocket(uri);
|
this._websocket = new WebSocket(uri);
|
||||||
this._websocket.onmessage = this._recv_message.bind(this);
|
this._websocket.onmessage = this._recv_message.bind(this);
|
||||||
this._websocket.binaryType = "arraybuffer";
|
this._websocket.binaryType = "arraybuffer";
|
||||||
|
this._latency = new Date().getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
latency(): number {
|
||||||
|
return this._latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(data: any) {
|
sendMessage(data: any) {
|
||||||
@ -63,6 +69,7 @@ export default class Websock {
|
|||||||
}
|
}
|
||||||
}, timeout);
|
}, timeout);
|
||||||
this._websocket.onopen = () => {
|
this._websocket.onopen = () => {
|
||||||
|
this._latency = new Date().getTime() - this._latency;
|
||||||
this._status = "open";
|
this._status = "open";
|
||||||
console.debug(">> WebSock.onopen");
|
console.debug(">> WebSock.onopen");
|
||||||
if (this._websocket?.protocol) {
|
if (this._websocket?.protocol) {
|
||||||
@ -72,28 +79,26 @@ export default class Websock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._eventHandlers.open();
|
this._eventHandlers.open();
|
||||||
console.debug("<< WebSock.onopen");
|
console.info("WebSock.onopen");
|
||||||
resolve(this);
|
resolve(this);
|
||||||
};
|
};
|
||||||
this._websocket.onclose = (e) => {
|
this._websocket.onclose = (e) => {
|
||||||
this._status = e;
|
this._status = e;
|
||||||
console.debug(">> WebSock.onclose");
|
console.error("WebSock.onclose: " + e);
|
||||||
this._eventHandlers.close(e);
|
this._eventHandlers.close(e);
|
||||||
console.debug("<< WebSock.onclose");
|
|
||||||
reject(e);
|
reject(e);
|
||||||
};
|
};
|
||||||
this._websocket.onerror = (e) => {
|
this._websocket.onerror = (e) => {
|
||||||
this._status = e;
|
this._status = e;
|
||||||
console.debug(">> WebSock.onerror: " + e);
|
console.error("WebSock.onerror: " + e);
|
||||||
this._eventHandlers.error(e);
|
this._eventHandlers.error(e);
|
||||||
console.debug("<< WebSock.onerror: " + e);
|
|
||||||
reject(e);
|
reject(e);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async next(timeout = 12000): Promise<Uint8Array> {
|
async next(timeout = 12000): Promise<Uint8Array> {
|
||||||
let func = (
|
const func = (
|
||||||
resolve: (value: Uint8Array) => void,
|
resolve: (value: Uint8Array) => void,
|
||||||
reject: (reason: any) => void,
|
reject: (reason: any) => void,
|
||||||
tm0: number
|
tm0: number
|
||||||
@ -102,7 +107,7 @@ export default class Websock {
|
|||||||
resolve(this._buf[0]);
|
resolve(this._buf[0]);
|
||||||
this._buf.splice(0, 1);
|
this._buf.splice(0, 1);
|
||||||
} else {
|
} else {
|
||||||
if (this._status != 'open') {
|
if (this._status != "open") {
|
||||||
reject(this._status);
|
reject(this._status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -134,7 +139,7 @@ export default class Websock {
|
|||||||
|
|
||||||
_recv_message(e: any) {
|
_recv_message(e: any) {
|
||||||
if (e.data instanceof window.ArrayBuffer) {
|
if (e.data instanceof window.ArrayBuffer) {
|
||||||
let bytes = new Uint8Array(e.data);
|
const bytes = new Uint8Array(e.data);
|
||||||
this._buf.push(bytes);
|
this._buf.push(bytes);
|
||||||
}
|
}
|
||||||
this._eventHandlers.message(e.data);
|
this._eventHandlers.message(e.data);
|
||||||
@ -146,13 +151,3 @@ export default class Websock {
|
|||||||
return hasher.digest();
|
return hasher.digest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ws = new Websock("ws://207.148.17.15:21118");
|
|
||||||
await ws.open();
|
|
||||||
console.log("ws connected");
|
|
||||||
// let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' });
|
|
||||||
// ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole }));
|
|
||||||
let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 });
|
|
||||||
ws.sendRendezvous({ testNatRequest });
|
|
||||||
let msg = ws.parseRendezvous(await ws.next());
|
|
||||||
console.log(msg);
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user