2023-01-12 17:39:23 +00:00
|
|
|
import Proxy from "./proxy.js";
|
|
|
|
import Socket from "./socket.js";
|
2023-02-06 10:50:48 +00:00
|
|
|
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;
|
2023-03-02 10:37:01 +00:00
|
|
|
export type OnData = (peer: Peer, data: any) => void;
|
2023-01-12 17:39:23 +00:00
|
|
|
export type OnReceive = OnData;
|
|
|
|
export type OnClose = OnData;
|
|
|
|
export type OnSend = OnData;
|
|
|
|
|
2023-03-02 10:37:01 +00:00
|
|
|
export type OnOpenBound = (
|
|
|
|
socket: Socket,
|
|
|
|
data: any
|
|
|
|
) =>
|
|
|
|
| { connect: boolean }
|
|
|
|
| Promise<{ connect: boolean }>
|
|
|
|
| Promise<void>
|
|
|
|
| void;
|
|
|
|
export type OnDataBound = (data: any) => void;
|
|
|
|
export type OnReceiveBound = OnDataBound;
|
|
|
|
export type OnCloseBound = OnDataBound;
|
|
|
|
export type OnSendBound = OnDataBound;
|
|
|
|
|
2023-01-12 17:39:23 +00:00
|
|
|
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;
|
2023-03-02 10:37:01 +00:00
|
|
|
private _onopen: OnOpenBound;
|
|
|
|
private _onreceive: OnReceiveBound;
|
|
|
|
private _onsend: OnSendBound;
|
|
|
|
private _onclose: OnCloseBound;
|
2023-02-26 03:16:40 +00:00
|
|
|
private _emulateWebsocket: boolean;
|
2023-01-12 17:39:23 +00:00
|
|
|
|
2023-03-02 10:25:50 +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;
|
2023-03-02 10:30:14 +00:00
|
|
|
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;
|
2023-03-02 10:25:50 +00:00
|
|
|
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([]);
|
|
|
|
}
|
2023-02-06 10:50:48 +00:00
|
|
|
|
|
|
|
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
|
|
|
});
|
2023-03-02 10:25:50 +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-02-06 10:50:48 +00:00
|
|
|
|
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);
|
|
|
|
},
|
|
|
|
});
|
2023-03-02 10:25:50 +00:00
|
|
|
const pipe = this._channel.addMessage({
|
2023-01-12 17:39:23 +00:00
|
|
|
async onmessage(m: any) {
|
2023-02-06 10:50:48 +00:00
|
|
|
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);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-03-02 10:25:50 +00:00
|
|
|
await this._channel.open();
|
2023-01-12 17:39:23 +00:00
|
|
|
}
|
|
|
|
}
|