libhyperproxy/src/peer.ts

119 lines
2.8 KiB
TypeScript
Raw Normal View History

2023-01-12 17:39:23 +00:00
import Proxy from "./proxy.js";
import Socket from "./socket.js";
import { Buffer } from "buffer";
2023-01-12 17:39:23 +00:00
export type OnOpen = (
2023-03-02 10:30:51 +00:00
peer: Peer,
2023-01-12 17:39:23 +00:00
socket: Socket,
data: any
) =>
| { connect: boolean }
| Promise<{ connect: boolean }>
| Promise<void>
| void;
export type OnData = (data: any) => void;
export type OnReceive = OnData;
export type OnClose = OnData;
export type OnSend = OnData;
export interface DataSocketOptions {
onopen?: OnOpen;
onreceive?: OnReceive;
onsend?: OnSend;
onclose?: OnClose;
2023-02-26 03:16:40 +00:00
emulateWebsocket?: boolean;
2023-01-12 17:39:23 +00:00
}
export interface PeerOptions {
peer: any;
muxer: any;
}
export interface PeerOptionsWithProxy extends PeerOptions {
proxy: Proxy;
}
export default class Peer {
private _proxy: Proxy;
private _peer: any;
private _muxer: any;
private _socket?: Socket;
private _onopen: OnOpen;
private _onreceive: OnReceive;
private _onsend: OnSend;
private _onclose: OnClose;
2023-02-26 03:16:40 +00:00
private _emulateWebsocket: boolean;
2023-01-12 17:39:23 +00:00
private _channel?: any;
2023-01-12 17:39:23 +00:00
constructor({
proxy,
peer,
muxer,
onopen,
onreceive,
onsend,
onclose,
2023-02-26 03:16:40 +00:00
emulateWebsocket = false,
2023-01-12 17:39:23 +00:00
}: PeerOptionsWithProxy & DataSocketOptions) {
this._proxy = proxy;
this._peer = peer;
this._muxer = muxer;
this._onopen = onopen?.bind(undefined, this);
this._onreceive = onreceive?.bind(undefined, this);
this._onsend = onsend?.bind(undefined, this);
this._onclose = onclose?.bind(undefined, this);
2023-02-26 03:16:40 +00:00
this._emulateWebsocket = emulateWebsocket;
2023-01-12 17:39:23 +00:00
}
async init() {
const write = async (data: any, cb: Function) => {
pipe.send(data);
await this._onsend?.(data);
cb();
};
const self = this;
this._channel = this._muxer.createChannel({
2023-01-12 17:39:23 +00:00
protocol: this._proxy.protocol,
async onopen(m: any) {
if (!m) {
m = Buffer.from([]);
}
if (m instanceof Uint8Array) {
m = Buffer.from(m);
}
2023-01-12 17:39:23 +00:00
self._socket = new Socket({
remoteAddress: self._peer.rawStream.remoteHost,
remotePort: self._peer.rawStream.remotePort,
2023-02-25 04:14:36 +00:00
remotePublicKey: self._peer.remotePublicKey,
2023-01-12 17:39:23 +00:00
write,
2023-02-26 03:16:40 +00:00
emulateWebsocket: self._emulateWebsocket,
2023-01-12 17:39:23 +00:00
});
self._socket.on("end", () => this._channel.close());
2023-01-12 17:39:23 +00:00
let ret = await self._onopen?.(self._socket, m);
if (!ret || (ret && ret.connect === false)) {
// @ts-ignore
self._socket.emit("connect");
}
2023-01-12 17:39:23 +00:00
self._socket.emit("data", m);
},
async onclose() {
2023-02-16 06:02:00 +00:00
self._socket?.destroy();
2023-01-12 17:39:23 +00:00
await self._onclose?.(self._socket);
},
});
const pipe = this._channel.addMessage({
2023-01-12 17:39:23 +00:00
async onmessage(m: any) {
if (m instanceof Uint8Array) {
m = Buffer.from(m);
}
2023-01-12 17:39:23 +00:00
self._socket.emit("data", m);
await self._onreceive?.(m);
},
});
await this._channel.open();
2023-01-12 17:39:23 +00:00
}
}