Compare commits
No commits in common. "5fa538524998e5b0c333424fcf6eab5347c6fee7" and "4b1b828c6997845c4a5552fcf9b4352395706128" have entirely different histories.
5fa5385249
...
4b1b828c69
|
@ -27,6 +27,7 @@ export interface DataSocketOptions {
|
||||||
onclose?: OnClose;
|
onclose?: OnClose;
|
||||||
onchannel?: OnChannel;
|
onchannel?: OnChannel;
|
||||||
emulateWebsocket?: boolean;
|
emulateWebsocket?: boolean;
|
||||||
|
createDefaultMessage?: boolean;
|
||||||
}
|
}
|
||||||
export interface PeerOptions {
|
export interface PeerOptions {
|
||||||
peer: any;
|
peer: any;
|
||||||
|
@ -35,25 +36,21 @@ export interface PeerOptions {
|
||||||
export interface PeerOptionsWithProxy extends PeerOptions {
|
export interface PeerOptionsWithProxy extends PeerOptions {
|
||||||
proxy: Proxy;
|
proxy: Proxy;
|
||||||
}
|
}
|
||||||
export default abstract class Peer {
|
export default class Peer {
|
||||||
protected _proxy: Proxy;
|
private _proxy;
|
||||||
protected _peer: any;
|
private _peer;
|
||||||
protected _muxer: any;
|
private _muxer;
|
||||||
protected _onopen: OnOpenBound;
|
private _onopen;
|
||||||
protected _onreceive: OnReceiveBound;
|
private _onreceive;
|
||||||
protected _onsend: OnSendBound;
|
private _onsend;
|
||||||
protected _onclose: OnCloseBound;
|
private _onclose;
|
||||||
protected _onchannel: OnChannelBound;
|
private _onchannel;
|
||||||
protected _emulateWebsocket: boolean;
|
private _emulateWebsocket;
|
||||||
constructor({ proxy, peer, muxer, onopen, onreceive, onsend, onclose, onchannel, emulateWebsocket, }: PeerOptionsWithProxy & DataSocketOptions);
|
private _createDefaultMessage;
|
||||||
protected _socket?: Socket;
|
constructor({ proxy, peer, muxer, onopen, onreceive, onsend, onclose, onchannel, emulateWebsocket, createDefaultMessage, }: PeerOptionsWithProxy & DataSocketOptions);
|
||||||
|
private _socket?;
|
||||||
get socket(): Socket;
|
get socket(): Socket;
|
||||||
protected _channel?: any;
|
private _channel?;
|
||||||
get channel(): any;
|
get channel(): any;
|
||||||
protected abstract initSocket(): any;
|
|
||||||
protected abstract handleChannelOnOpen(m: any): Promise<void>;
|
|
||||||
protected abstract handleChannelOnClose(socket: Socket): Promise<void>;
|
|
||||||
protected initChannel(): Promise<void>;
|
|
||||||
init(): Promise<void>;
|
init(): Promise<void>;
|
||||||
protected initMessages(): Promise<void>;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const socket_js_1 = __importDefault(require("./socket.js"));
|
||||||
|
const buffer_1 = require("buffer");
|
||||||
class Peer {
|
class Peer {
|
||||||
_proxy;
|
_proxy;
|
||||||
_peer;
|
_peer;
|
||||||
|
@ -10,7 +15,8 @@ class Peer {
|
||||||
_onclose;
|
_onclose;
|
||||||
_onchannel;
|
_onchannel;
|
||||||
_emulateWebsocket;
|
_emulateWebsocket;
|
||||||
constructor({ proxy, peer, muxer, onopen, onreceive, onsend, onclose, onchannel, emulateWebsocket = false, }) {
|
_createDefaultMessage;
|
||||||
|
constructor({ proxy, peer, muxer, onopen, onreceive, onsend, onclose, onchannel, emulateWebsocket = false, createDefaultMessage = true, }) {
|
||||||
this._proxy = proxy;
|
this._proxy = proxy;
|
||||||
this._peer = peer;
|
this._peer = peer;
|
||||||
this._muxer = muxer;
|
this._muxer = muxer;
|
||||||
|
@ -20,6 +26,7 @@ class Peer {
|
||||||
this._onclose = onclose?.bind(undefined, this);
|
this._onclose = onclose?.bind(undefined, this);
|
||||||
this._onchannel = onchannel?.bind(undefined, this);
|
this._onchannel = onchannel?.bind(undefined, this);
|
||||||
this._emulateWebsocket = emulateWebsocket;
|
this._emulateWebsocket = emulateWebsocket;
|
||||||
|
this._createDefaultMessage = createDefaultMessage;
|
||||||
}
|
}
|
||||||
_socket;
|
_socket;
|
||||||
get socket() {
|
get socket() {
|
||||||
|
@ -29,21 +36,72 @@ class Peer {
|
||||||
get channel() {
|
get channel() {
|
||||||
return this._channel;
|
return this._channel;
|
||||||
}
|
}
|
||||||
async initChannel() {
|
async init() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
let pipe;
|
||||||
|
const raw = await maybeGetAsyncProperty(self._peer.rawStream);
|
||||||
|
this._socket = new socket_js_1.default({
|
||||||
|
remoteAddress: raw.remoteHost,
|
||||||
|
remotePort: raw.remotePort,
|
||||||
|
remotePublicKey: await maybeGetAsyncProperty(self._peer.remotePublicKey),
|
||||||
|
async write(data, cb) {
|
||||||
|
if (pipe) {
|
||||||
|
pipe.send(data);
|
||||||
|
}
|
||||||
|
await self._onsend?.(data);
|
||||||
|
cb();
|
||||||
|
},
|
||||||
|
emulateWebsocket: self._emulateWebsocket,
|
||||||
|
});
|
||||||
this._channel = await this._muxer.createChannel({
|
this._channel = await this._muxer.createChannel({
|
||||||
protocol: this._proxy.protocol,
|
protocol: this._proxy.protocol,
|
||||||
onopen: this.handleChannelOnOpen.bind(this),
|
async onopen(m) {
|
||||||
onclose: this.handleChannelOnClose.bind(this),
|
if (!m) {
|
||||||
|
m = buffer_1.Buffer.from([]);
|
||||||
|
}
|
||||||
|
if (m instanceof Uint8Array) {
|
||||||
|
m = buffer_1.Buffer.from(m);
|
||||||
|
}
|
||||||
|
self._socket.on("end", () => this._channel.close());
|
||||||
|
let ret = await self._onopen?.(self._socket, m);
|
||||||
|
if (!ret || (ret && ret.connect === false)) {
|
||||||
|
// @ts-ignore
|
||||||
|
self._socket.emit("connect");
|
||||||
|
}
|
||||||
|
self._socket.emit("data", m);
|
||||||
|
},
|
||||||
|
async onclose() {
|
||||||
|
self._socket?.destroy();
|
||||||
|
await self._onclose?.(self._socket);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await this.initMessages();
|
if (this._createDefaultMessage) {
|
||||||
|
pipe = await this._channel.addMessage({
|
||||||
|
async onmessage(m) {
|
||||||
|
if (m instanceof Uint8Array) {
|
||||||
|
m = buffer_1.Buffer.from(m);
|
||||||
|
}
|
||||||
|
self._socket.emit("data", m);
|
||||||
|
await self._onreceive?.(m);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
await this._onchannel?.(this._channel);
|
await this._onchannel?.(this._channel);
|
||||||
await this._channel.open();
|
await this._channel.open();
|
||||||
}
|
}
|
||||||
async init() {
|
|
||||||
await this.initSocket();
|
|
||||||
await this.initChannel();
|
|
||||||
}
|
|
||||||
async initMessages() { }
|
|
||||||
}
|
}
|
||||||
exports.default = Peer;
|
exports.default = Peer;
|
||||||
|
async function maybeGetAsyncProperty(object) {
|
||||||
|
if (typeof object === "function") {
|
||||||
|
object = object();
|
||||||
|
}
|
||||||
|
if (isPromise(object)) {
|
||||||
|
object = await object;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
function isPromise(obj) {
|
||||||
|
return (!!obj &&
|
||||||
|
(typeof obj === "object" || typeof obj === "function") &&
|
||||||
|
typeof obj.then === "function");
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import Proxy from "../proxy.js";
|
import Proxy from "../proxy.js";
|
||||||
import { DataSocketOptions, PeerOptions } from "../peer.js";
|
|
||||||
export default class BasicProxy extends Proxy {
|
export default class BasicProxy extends Proxy {
|
||||||
protected handlePeer({ peer, muxer, ...options }: DataSocketOptions & PeerOptions): void;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const proxy_js_1 = __importDefault(require("../proxy.js"));
|
const proxy_js_1 = __importDefault(require("../proxy.js"));
|
||||||
const peer_js_1 = __importDefault(require("./basic/peer.js"));
|
|
||||||
class BasicProxy extends proxy_js_1.default {
|
class BasicProxy extends proxy_js_1.default {
|
||||||
handlePeer({ peer, muxer, ...options }) {
|
|
||||||
const conn = new peer_js_1.default({ proxy: this, peer, muxer, ...options });
|
|
||||||
conn.init();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exports.default = BasicProxy;
|
exports.default = BasicProxy;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import BasePeer from "../../peer.js";
|
|
||||||
import Socket from "../../socket.js";
|
|
||||||
export default class Peer extends BasePeer {
|
|
||||||
private _pipe?;
|
|
||||||
protected initSocket(): Promise<void>;
|
|
||||||
protected handleChannelOnOpen(m: any): Promise<void>;
|
|
||||||
protected handleChannelOnClose(socket: Socket): Promise<void>;
|
|
||||||
protected initMessages(): Promise<void>;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const peer_js_1 = __importDefault(require("../../peer.js"));
|
|
||||||
const util_js_1 = require("../../util.js");
|
|
||||||
const socket_js_1 = __importDefault(require("../../socket.js"));
|
|
||||||
const buffer_1 = require("buffer");
|
|
||||||
class Peer extends peer_js_1.default {
|
|
||||||
_pipe;
|
|
||||||
async initSocket() {
|
|
||||||
const self = this;
|
|
||||||
const raw = await (0, util_js_1.maybeGetAsyncProperty)(self._peer.rawStream);
|
|
||||||
this._socket = new socket_js_1.default({
|
|
||||||
remoteAddress: raw.remoteHost,
|
|
||||||
remotePort: raw.remotePort,
|
|
||||||
remotePublicKey: await (0, util_js_1.maybeGetAsyncProperty)(self._peer.remotePublicKey),
|
|
||||||
async write(data, cb) {
|
|
||||||
self._pipe?.send(data);
|
|
||||||
await self._onsend?.(data);
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
emulateWebsocket: self._emulateWebsocket,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async handleChannelOnOpen(m) {
|
|
||||||
if (!m) {
|
|
||||||
m = buffer_1.Buffer.from([]);
|
|
||||||
}
|
|
||||||
if (m instanceof Uint8Array) {
|
|
||||||
m = buffer_1.Buffer.from(m);
|
|
||||||
}
|
|
||||||
this._socket?.on("end", () => this._channel.close());
|
|
||||||
let ret = await this._onopen?.(this._socket, m);
|
|
||||||
if (!ret || (ret && ret.connect === false)) {
|
|
||||||
// @ts-ignore
|
|
||||||
self._socket?.emit("connect");
|
|
||||||
}
|
|
||||||
this._socket?.emit("data", m);
|
|
||||||
}
|
|
||||||
async handleChannelOnClose(socket) {
|
|
||||||
this._socket?.destroy();
|
|
||||||
await this._onclose?.(this._socket);
|
|
||||||
}
|
|
||||||
async initMessages() {
|
|
||||||
const self = this;
|
|
||||||
this._pipe = await this._channel.addMessage({
|
|
||||||
async onmessage(m) {
|
|
||||||
if (m instanceof Uint8Array) {
|
|
||||||
m = buffer_1.Buffer.from(m);
|
|
||||||
}
|
|
||||||
self._socket.emit("data", m);
|
|
||||||
await self._onreceive?.(m);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = Peer;
|
|
|
@ -1,7 +1,7 @@
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import Proxy, { ProxyOptions } from "../proxy.js";
|
import Proxy, { ProxyOptions } from "../proxy.js";
|
||||||
import type { TcpSocketConnectOpts } from "net";
|
import type { TcpSocketConnectOpts } from "net";
|
||||||
import Peer, { DataSocketOptions, PeerOptions } from "../peer.js";
|
import Peer from "../peer.js";
|
||||||
import { PeerEntity } from "./multiSocket/types.js";
|
import { PeerEntity } from "./multiSocket/types.js";
|
||||||
export interface MultiSocketProxyOptions extends ProxyOptions {
|
export interface MultiSocketProxyOptions extends ProxyOptions {
|
||||||
socketClass?: any;
|
socketClass?: any;
|
||||||
|
@ -9,7 +9,6 @@ export interface MultiSocketProxyOptions extends ProxyOptions {
|
||||||
allowedPorts?: number[];
|
allowedPorts?: number[];
|
||||||
}
|
}
|
||||||
export default class MultiSocketProxy extends Proxy {
|
export default class MultiSocketProxy extends Proxy {
|
||||||
handlePeer({ peer, muxer, ...options }: DataSocketOptions & PeerOptions): void;
|
|
||||||
private socketClass;
|
private socketClass;
|
||||||
private _peers;
|
private _peers;
|
||||||
private _nextPeer;
|
private _nextPeer;
|
||||||
|
|
|
@ -54,14 +54,16 @@ const errorSocketEncoding = {
|
||||||
};
|
};
|
||||||
const nextSocketId = (0, util_js_1.idFactory)(1);
|
const nextSocketId = (0, util_js_1.idFactory)(1);
|
||||||
class MultiSocketProxy extends proxy_js_1.default {
|
class MultiSocketProxy extends proxy_js_1.default {
|
||||||
handlePeer({ peer, muxer, ...options }) { }
|
|
||||||
socketClass;
|
socketClass;
|
||||||
_peers = new Map();
|
_peers = new Map();
|
||||||
_nextPeer = (0, util_js_1.roundRobinFactory)(this._peers);
|
_nextPeer = (0, util_js_1.roundRobinFactory)(this._peers);
|
||||||
_server = false;
|
_server = false;
|
||||||
_allowedPorts = [];
|
_allowedPorts = [];
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super({
|
||||||
|
createDefaultMessage: false,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
this._socketOptions.onchannel = this.handleNewPeerChannel.bind(this);
|
this._socketOptions.onchannel = this.handleNewPeerChannel.bind(this);
|
||||||
this._socketOptions.onclose = this.handleClosePeer.bind(this);
|
this._socketOptions.onclose = this.handleClosePeer.bind(this);
|
||||||
this._socketOptions.onopen = this.handlePeer.bind(this);
|
this._socketOptions.onopen = this.handlePeer.bind(this);
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import { Callback } from "streamx";
|
import { Callback, Duplex } from "streamx";
|
||||||
import { TcpSocketConnectOpts } from "net";
|
import { TcpSocketConnectOpts } from "net";
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
import MultiSocketProxy from "../multiSocket.js";
|
||||||
import { PeerEntity } from "./types.js";
|
import { PeerEntity } from "./types.js";
|
||||||
import Socket, { SocketOptions } from "../../socket.js";
|
export default class DummySocket extends Duplex {
|
||||||
export default class DummySocket extends Socket {
|
|
||||||
private _options;
|
private _options;
|
||||||
private _id;
|
private _id;
|
||||||
private _proxy;
|
private _proxy;
|
||||||
private _connectTimeout?;
|
private _connectTimeout?;
|
||||||
constructor(id: number, manager: MultiSocketProxy, peer: PeerEntity, connectOptions: TcpSocketConnectOpts, socketOptions: SocketOptions);
|
constructor(id: number, manager: MultiSocketProxy, peer: PeerEntity, options: TcpSocketConnectOpts);
|
||||||
private _remoteId;
|
private _remoteId;
|
||||||
set remoteId(value: number);
|
set remoteId(value: number);
|
||||||
private _peer;
|
private _peer;
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const streamx_1 = require("streamx");
|
||||||
const timers_1 = require("timers");
|
const timers_1 = require("timers");
|
||||||
const util_js_1 = require("../../util.js");
|
const util_js_1 = require("../../util.js");
|
||||||
const socket_js_1 = __importDefault(require("../../socket.js"));
|
class DummySocket extends streamx_1.Duplex {
|
||||||
class DummySocket extends socket_js_1.default {
|
|
||||||
_options;
|
_options;
|
||||||
_id;
|
_id;
|
||||||
_proxy;
|
_proxy;
|
||||||
_connectTimeout;
|
_connectTimeout;
|
||||||
constructor(id, manager, peer, connectOptions, socketOptions) {
|
constructor(id, manager, peer, options) {
|
||||||
super(socketOptions);
|
super();
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._proxy = manager;
|
this._proxy = manager;
|
||||||
this._peer = peer;
|
this._peer = peer;
|
||||||
this._options = connectOptions;
|
this._options = options;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.on("timeout", () => {
|
this.on("timeout", () => {
|
||||||
if (this._connectTimeout) {
|
if (this._connectTimeout) {
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import BasePeer from "../../peer.js";
|
|
||||||
import Socket from "../../socket.js";
|
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
|
||||||
export default class Peer extends BasePeer {
|
|
||||||
protected _proxy: MultiSocketProxy;
|
|
||||||
protected initSocket(): Promise<void>;
|
|
||||||
protected handleChannelOnClose(socket: Socket): Promise<void>;
|
|
||||||
protected handleChannelOnOpen(m: any): Promise<void>;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const peer_js_1 = __importDefault(require("../../peer.js"));
|
|
||||||
class Peer extends peer_js_1.default {
|
|
||||||
async initSocket() { }
|
|
||||||
async handleChannelOnClose(socket) {
|
|
||||||
return this._proxy.handleClosePeer(this);
|
|
||||||
}
|
|
||||||
async handleChannelOnOpen(m) {
|
|
||||||
await this._proxy.handleNewPeerChannel(this._peer, this._channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = Peer;
|
|
|
@ -1,10 +1,9 @@
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import { Callback } from "streamx";
|
import { Callback, Duplex } from "streamx";
|
||||||
import { TcpSocketConnectOpts } from "net";
|
import { TcpSocketConnectOpts } from "net";
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
import MultiSocketProxy from "../multiSocket.js";
|
||||||
import { PeerEntity } from "./types.js";
|
import { PeerEntity } from "./types.js";
|
||||||
import BaseSocket from "../../socket.js";
|
export default class TcpSocket extends Duplex {
|
||||||
export default class TcpSocket extends BaseSocket {
|
|
||||||
private _options;
|
private _options;
|
||||||
private _id;
|
private _id;
|
||||||
private _remoteId;
|
private _remoteId;
|
||||||
|
|
|
@ -22,13 +22,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
__setModuleDefault(result, mod);
|
__setModuleDefault(result, mod);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const streamx_1 = require("streamx");
|
||||||
const net = __importStar(require("net"));
|
const net = __importStar(require("net"));
|
||||||
const socket_js_1 = __importDefault(require("../../socket.js"));
|
class TcpSocket extends streamx_1.Duplex {
|
||||||
class TcpSocket extends socket_js_1.default {
|
|
||||||
_options;
|
_options;
|
||||||
_id;
|
_id;
|
||||||
_remoteId;
|
_remoteId;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataSocketOptions, PeerOptions } from "./peer.js";
|
import { PeerOptions, DataSocketOptions } from "./peer.js";
|
||||||
export interface ProxyOptions extends DataSocketOptions {
|
export interface ProxyOptions extends DataSocketOptions {
|
||||||
swarm: any;
|
swarm: any;
|
||||||
protocol: string;
|
protocol: string;
|
||||||
|
@ -8,14 +8,14 @@ export interface ProxyOptions extends DataSocketOptions {
|
||||||
export default abstract class Proxy {
|
export default abstract class Proxy {
|
||||||
protected _listen: any;
|
protected _listen: any;
|
||||||
protected _autostart: boolean;
|
protected _autostart: boolean;
|
||||||
constructor({ swarm, protocol, onopen, onreceive, onsend, onclose, onchannel, listen, autostart, emulateWebsocket, }: ProxyOptions);
|
constructor({ swarm, protocol, onopen, onreceive, onsend, onclose, onchannel, listen, autostart, emulateWebsocket, createDefaultMessage, }: ProxyOptions);
|
||||||
protected _socketOptions: DataSocketOptions;
|
protected _socketOptions: DataSocketOptions;
|
||||||
get socketOptions(): DataSocketOptions;
|
get socketOptions(): DataSocketOptions;
|
||||||
private _swarm;
|
private _swarm;
|
||||||
get swarm(): any;
|
get swarm(): any;
|
||||||
private _protocol;
|
private _protocol;
|
||||||
get protocol(): string;
|
get protocol(): string;
|
||||||
protected abstract handlePeer({ peer, muxer, ...options }: DataSocketOptions & PeerOptions): any;
|
handlePeer({ peer, muxer, ...options }: DataSocketOptions & PeerOptions): void;
|
||||||
protected _init(): void;
|
protected _init(): void;
|
||||||
private init;
|
private init;
|
||||||
private _handleConnection;
|
private _handleConnection;
|
||||||
|
|
|
@ -4,10 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const protomux_1 = __importDefault(require("protomux"));
|
const protomux_1 = __importDefault(require("protomux"));
|
||||||
|
const peer_js_1 = __importDefault(require("./peer.js"));
|
||||||
class Proxy {
|
class Proxy {
|
||||||
_listen;
|
_listen;
|
||||||
_autostart;
|
_autostart;
|
||||||
constructor({ swarm, protocol, onopen, onreceive, onsend, onclose, onchannel, listen = false, autostart = false, emulateWebsocket = false, }) {
|
constructor({ swarm, protocol, onopen, onreceive, onsend, onclose, onchannel, listen = false, autostart = false, emulateWebsocket = false, createDefaultMessage = true, }) {
|
||||||
this._swarm = swarm;
|
this._swarm = swarm;
|
||||||
this._protocol = protocol;
|
this._protocol = protocol;
|
||||||
this._listen = listen;
|
this._listen = listen;
|
||||||
|
@ -19,6 +20,7 @@ class Proxy {
|
||||||
onclose,
|
onclose,
|
||||||
onchannel,
|
onchannel,
|
||||||
emulateWebsocket,
|
emulateWebsocket,
|
||||||
|
createDefaultMessage,
|
||||||
};
|
};
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,10 @@ class Proxy {
|
||||||
get protocol() {
|
get protocol() {
|
||||||
return this._protocol;
|
return this._protocol;
|
||||||
}
|
}
|
||||||
|
handlePeer({ peer, muxer, ...options }) {
|
||||||
|
const conn = new peer_js_1.default({ proxy: this, peer, muxer, ...options });
|
||||||
|
conn.init();
|
||||||
|
}
|
||||||
_init() {
|
_init() {
|
||||||
// Implement in subclasses
|
// Implement in subclasses
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Duplex, DuplexEvents, Callback } from "streamx";
|
import { Duplex, DuplexEvents, Callback } from "streamx";
|
||||||
type AddressFamily = "IPv6" | "IPv4";
|
type AddressFamily = "IPv6" | "IPv4";
|
||||||
export interface SocketOptions {
|
interface SocketOptions {
|
||||||
allowHalfOpen?: boolean;
|
allowHalfOpen?: boolean;
|
||||||
remoteAddress?: string;
|
remoteAddress?: string;
|
||||||
remotePort?: number;
|
remotePort?: number;
|
||||||
|
|
110
src/peer.ts
110
src/peer.ts
|
@ -1,7 +1,6 @@
|
||||||
import Proxy from "./proxy.js";
|
import Proxy from "./proxy.js";
|
||||||
import Socket from "./socket.js";
|
import Socket from "./socket.js";
|
||||||
import { Buffer } from "buffer";
|
import { Buffer } from "buffer";
|
||||||
import { maybeGetAsyncProperty } from "./util.js";
|
|
||||||
export type OnOpen = (
|
export type OnOpen = (
|
||||||
peer: Peer,
|
peer: Peer,
|
||||||
socket: Socket,
|
socket: Socket,
|
||||||
|
@ -39,6 +38,7 @@ export interface DataSocketOptions {
|
||||||
onclose?: OnClose;
|
onclose?: OnClose;
|
||||||
onchannel?: OnChannel;
|
onchannel?: OnChannel;
|
||||||
emulateWebsocket?: boolean;
|
emulateWebsocket?: boolean;
|
||||||
|
createDefaultMessage?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeerOptions {
|
export interface PeerOptions {
|
||||||
|
@ -50,16 +50,17 @@ export interface PeerOptionsWithProxy extends PeerOptions {
|
||||||
proxy: Proxy;
|
proxy: Proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default abstract class Peer {
|
export default class Peer {
|
||||||
protected _proxy: Proxy;
|
private _proxy: Proxy;
|
||||||
protected _peer: any;
|
private _peer: any;
|
||||||
protected _muxer: any;
|
private _muxer: any;
|
||||||
protected _onopen: OnOpenBound;
|
private _onopen: OnOpenBound;
|
||||||
protected _onreceive: OnReceiveBound;
|
private _onreceive: OnReceiveBound;
|
||||||
protected _onsend: OnSendBound;
|
private _onsend: OnSendBound;
|
||||||
protected _onclose: OnCloseBound;
|
private _onclose: OnCloseBound;
|
||||||
protected _onchannel: OnChannelBound;
|
private _onchannel: OnChannelBound;
|
||||||
protected _emulateWebsocket: boolean;
|
private _emulateWebsocket: boolean;
|
||||||
|
private _createDefaultMessage: boolean;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
proxy,
|
proxy,
|
||||||
|
@ -71,6 +72,7 @@ export default abstract class Peer {
|
||||||
onclose,
|
onclose,
|
||||||
onchannel,
|
onchannel,
|
||||||
emulateWebsocket = false,
|
emulateWebsocket = false,
|
||||||
|
createDefaultMessage = true,
|
||||||
}: PeerOptionsWithProxy & DataSocketOptions) {
|
}: PeerOptionsWithProxy & DataSocketOptions) {
|
||||||
this._proxy = proxy;
|
this._proxy = proxy;
|
||||||
this._peer = peer;
|
this._peer = peer;
|
||||||
|
@ -81,44 +83,98 @@ export default abstract class Peer {
|
||||||
this._onclose = onclose?.bind(undefined, this);
|
this._onclose = onclose?.bind(undefined, this);
|
||||||
this._onchannel = onchannel?.bind(undefined, this);
|
this._onchannel = onchannel?.bind(undefined, this);
|
||||||
this._emulateWebsocket = emulateWebsocket;
|
this._emulateWebsocket = emulateWebsocket;
|
||||||
|
this._createDefaultMessage = createDefaultMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _socket?: Socket;
|
private _socket?: Socket;
|
||||||
|
|
||||||
get socket(): Socket {
|
get socket(): Socket {
|
||||||
return this._socket;
|
return this._socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _channel?: any;
|
private _channel?: any;
|
||||||
|
|
||||||
get channel(): any {
|
get channel(): any {
|
||||||
return this._channel;
|
return this._channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract initSocket();
|
async init() {
|
||||||
|
|
||||||
protected abstract handleChannelOnOpen(m: any): Promise<void>;
|
|
||||||
protected abstract handleChannelOnClose(socket: Socket): Promise<void>;
|
|
||||||
|
|
||||||
protected async initChannel() {
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
let pipe;
|
||||||
|
const raw = await maybeGetAsyncProperty(self._peer.rawStream);
|
||||||
|
this._socket = new Socket({
|
||||||
|
remoteAddress: raw.remoteHost,
|
||||||
|
remotePort: raw.remotePort,
|
||||||
|
remotePublicKey: await maybeGetAsyncProperty(self._peer.remotePublicKey),
|
||||||
|
async write(data: any, cb: Function) {
|
||||||
|
if (pipe) {
|
||||||
|
pipe.send(data);
|
||||||
|
}
|
||||||
|
await self._onsend?.(data);
|
||||||
|
cb();
|
||||||
|
},
|
||||||
|
emulateWebsocket: self._emulateWebsocket,
|
||||||
|
});
|
||||||
|
|
||||||
this._channel = await this._muxer.createChannel({
|
this._channel = await this._muxer.createChannel({
|
||||||
protocol: this._proxy.protocol,
|
protocol: this._proxy.protocol,
|
||||||
onopen: this.handleChannelOnOpen.bind(this),
|
async onopen(m: any) {
|
||||||
onclose: this.handleChannelOnClose.bind(this),
|
if (!m) {
|
||||||
|
m = Buffer.from([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m instanceof Uint8Array) {
|
||||||
|
m = Buffer.from(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
self._socket.on("end", () => this._channel.close());
|
||||||
|
let ret = await self._onopen?.(self._socket, m);
|
||||||
|
if (!ret || (ret && ret.connect === false)) {
|
||||||
|
// @ts-ignore
|
||||||
|
self._socket.emit("connect");
|
||||||
|
}
|
||||||
|
|
||||||
|
self._socket.emit("data", m);
|
||||||
|
},
|
||||||
|
async onclose() {
|
||||||
|
self._socket?.destroy();
|
||||||
|
await self._onclose?.(self._socket);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.initMessages();
|
if (this._createDefaultMessage) {
|
||||||
|
pipe = await this._channel.addMessage({
|
||||||
|
async onmessage(m: any) {
|
||||||
|
if (m instanceof Uint8Array) {
|
||||||
|
m = Buffer.from(m);
|
||||||
|
}
|
||||||
|
self._socket.emit("data", m);
|
||||||
|
await self._onreceive?.(m);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await this._onchannel?.(this._channel);
|
await this._onchannel?.(this._channel);
|
||||||
await this._channel.open();
|
await this._channel.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
|
||||||
await this.initSocket();
|
|
||||||
await this.initChannel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async initMessages() {}
|
async function maybeGetAsyncProperty(object: any) {
|
||||||
|
if (typeof object === "function") {
|
||||||
|
object = object();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPromise(object)) {
|
||||||
|
object = await object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPromise(obj: Promise<any>) {
|
||||||
|
return (
|
||||||
|
!!obj &&
|
||||||
|
(typeof obj === "object" || typeof obj === "function") &&
|
||||||
|
typeof obj.then === "function"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
import Proxy from "../proxy.js";
|
import Proxy from "../proxy.js";
|
||||||
import { DataSocketOptions, PeerOptions } from "../peer.js";
|
|
||||||
import BasicPeer from "./basic/peer.js";
|
|
||||||
|
|
||||||
export default class BasicProxy extends Proxy {
|
export default class BasicProxy extends Proxy {}
|
||||||
protected handlePeer({
|
|
||||||
peer,
|
|
||||||
muxer,
|
|
||||||
...options
|
|
||||||
}: DataSocketOptions & PeerOptions) {
|
|
||||||
const conn = new BasicPeer({ proxy: this, peer, muxer, ...options });
|
|
||||||
conn.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
import BasePeer from "../../peer.js";
|
|
||||||
import { maybeGetAsyncProperty } from "../../util.js";
|
|
||||||
import Socket from "../../socket.js";
|
|
||||||
import { Buffer } from "buffer";
|
|
||||||
|
|
||||||
export default class Peer extends BasePeer {
|
|
||||||
private _pipe?: any;
|
|
||||||
protected async initSocket() {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
const raw = await maybeGetAsyncProperty(self._peer.rawStream);
|
|
||||||
this._socket = new Socket({
|
|
||||||
remoteAddress: raw.remoteHost,
|
|
||||||
remotePort: raw.remotePort,
|
|
||||||
remotePublicKey: await maybeGetAsyncProperty(self._peer.remotePublicKey),
|
|
||||||
async write(data: any, cb: Function) {
|
|
||||||
self._pipe?.send(data);
|
|
||||||
await self._onsend?.(data);
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
emulateWebsocket: self._emulateWebsocket,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async handleChannelOnOpen(m: any) {
|
|
||||||
if (!m) {
|
|
||||||
m = Buffer.from([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m instanceof Uint8Array) {
|
|
||||||
m = Buffer.from(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._socket?.on("end", () => this._channel.close());
|
|
||||||
let ret = await this._onopen?.(this._socket, m);
|
|
||||||
if (!ret || (ret && ret.connect === false)) {
|
|
||||||
// @ts-ignore
|
|
||||||
self._socket?.emit("connect");
|
|
||||||
}
|
|
||||||
|
|
||||||
this._socket?.emit("data", m);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async handleChannelOnClose(socket: Socket): Promise<void> {
|
|
||||||
this._socket?.destroy();
|
|
||||||
await this._onclose?.(this._socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async initMessages(): Promise<void> {
|
|
||||||
const self = this;
|
|
||||||
this._pipe = await this._channel.addMessage({
|
|
||||||
async onmessage(m: any) {
|
|
||||||
if (m instanceof Uint8Array) {
|
|
||||||
m = Buffer.from(m);
|
|
||||||
}
|
|
||||||
self._socket.emit("data", m);
|
|
||||||
await self._onreceive?.(m);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ import { json, raw, uint } from "compact-encoding";
|
||||||
import { deserializeError } from "serialize-error";
|
import { deserializeError } from "serialize-error";
|
||||||
import b4a from "b4a";
|
import b4a from "b4a";
|
||||||
import type { TcpSocketConnectOpts } from "net";
|
import type { TcpSocketConnectOpts } from "net";
|
||||||
import Peer, { DataSocketOptions, PeerOptions } from "../peer.js";
|
import Peer from "../peer.js";
|
||||||
import { roundRobinFactory, idFactory } from "../util.js";
|
import { roundRobinFactory, idFactory } from "../util.js";
|
||||||
import {
|
import {
|
||||||
CloseSocketRequest,
|
CloseSocketRequest,
|
||||||
|
@ -69,7 +69,6 @@ const errorSocketEncoding = {
|
||||||
const nextSocketId = idFactory(1);
|
const nextSocketId = idFactory(1);
|
||||||
|
|
||||||
export default class MultiSocketProxy extends Proxy {
|
export default class MultiSocketProxy extends Proxy {
|
||||||
handlePeer({ peer, muxer, ...options }: DataSocketOptions & PeerOptions) {}
|
|
||||||
private socketClass: any;
|
private socketClass: any;
|
||||||
private _peers: Map<string, PeerEntity> = new Map<string, PeerEntity>();
|
private _peers: Map<string, PeerEntity> = new Map<string, PeerEntity>();
|
||||||
private _nextPeer = roundRobinFactory(this._peers);
|
private _nextPeer = roundRobinFactory(this._peers);
|
||||||
|
@ -77,7 +76,10 @@ export default class MultiSocketProxy extends Proxy {
|
||||||
private _allowedPorts = [];
|
private _allowedPorts = [];
|
||||||
|
|
||||||
constructor(options: MultiSocketProxyOptions) {
|
constructor(options: MultiSocketProxyOptions) {
|
||||||
super(options);
|
super({
|
||||||
|
createDefaultMessage: false,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
this._socketOptions.onchannel = this.handleNewPeerChannel.bind(this);
|
this._socketOptions.onchannel = this.handleNewPeerChannel.bind(this);
|
||||||
this._socketOptions.onclose = this.handleClosePeer.bind(this);
|
this._socketOptions.onclose = this.handleClosePeer.bind(this);
|
||||||
this._socketOptions.onopen = this.handlePeer.bind(this);
|
this._socketOptions.onopen = this.handlePeer.bind(this);
|
||||||
|
|
|
@ -4,9 +4,8 @@ import { clearTimeout } from "timers";
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
import MultiSocketProxy from "../multiSocket.js";
|
||||||
import { PeerEntity, SocketRequest, WriteSocketRequest } from "./types.js";
|
import { PeerEntity, SocketRequest, WriteSocketRequest } from "./types.js";
|
||||||
import { maybeGetAsyncProperty } from "../../util.js";
|
import { maybeGetAsyncProperty } from "../../util.js";
|
||||||
import Socket, { SocketOptions } from "../../socket.js";
|
|
||||||
|
|
||||||
export default class DummySocket extends Socket {
|
export default class DummySocket extends Duplex {
|
||||||
private _options: TcpSocketConnectOpts;
|
private _options: TcpSocketConnectOpts;
|
||||||
private _id: number;
|
private _id: number;
|
||||||
private _proxy: MultiSocketProxy;
|
private _proxy: MultiSocketProxy;
|
||||||
|
@ -17,14 +16,13 @@ export default class DummySocket extends Socket {
|
||||||
id: number,
|
id: number,
|
||||||
manager: MultiSocketProxy,
|
manager: MultiSocketProxy,
|
||||||
peer: PeerEntity,
|
peer: PeerEntity,
|
||||||
connectOptions: TcpSocketConnectOpts,
|
options: TcpSocketConnectOpts
|
||||||
socketOptions: SocketOptions
|
|
||||||
) {
|
) {
|
||||||
super(socketOptions);
|
super();
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._proxy = manager;
|
this._proxy = manager;
|
||||||
this._peer = peer;
|
this._peer = peer;
|
||||||
this._options = connectOptions;
|
this._options = options;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.on("timeout", () => {
|
this.on("timeout", () => {
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import BasePeer from "../../peer.js";
|
|
||||||
import Socket from "../../socket.js";
|
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
|
||||||
|
|
||||||
export default class Peer extends BasePeer {
|
|
||||||
protected declare _proxy: MultiSocketProxy;
|
|
||||||
protected async initSocket() {}
|
|
||||||
|
|
||||||
protected async handleChannelOnClose(socket: Socket): Promise<void> {
|
|
||||||
return this._proxy.handleClosePeer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async handleChannelOnOpen(m: any): Promise<void> {
|
|
||||||
await this._proxy.handleNewPeerChannel(this._peer, this._channel);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,9 +3,8 @@ import { Socket, TcpSocketConnectOpts } from "net";
|
||||||
import MultiSocketProxy from "../multiSocket.js";
|
import MultiSocketProxy from "../multiSocket.js";
|
||||||
import { PeerEntity, SocketRequest, WriteSocketRequest } from "./types.js";
|
import { PeerEntity, SocketRequest, WriteSocketRequest } from "./types.js";
|
||||||
import * as net from "net";
|
import * as net from "net";
|
||||||
import BaseSocket from "../../socket.js";
|
|
||||||
|
|
||||||
export default class TcpSocket extends BaseSocket {
|
export default class TcpSocket extends Duplex {
|
||||||
private _options;
|
private _options;
|
||||||
private _id: number;
|
private _id: number;
|
||||||
private _remoteId: number;
|
private _remoteId: number;
|
||||||
|
|
12
src/proxy.ts
12
src/proxy.ts
|
@ -1,5 +1,5 @@
|
||||||
import Protomux from "protomux";
|
import Protomux from "protomux";
|
||||||
import { DataSocketOptions, PeerOptions } from "./peer.js";
|
import Peer, { PeerOptions, DataSocketOptions } from "./peer.js";
|
||||||
|
|
||||||
export interface ProxyOptions extends DataSocketOptions {
|
export interface ProxyOptions extends DataSocketOptions {
|
||||||
swarm: any;
|
swarm: any;
|
||||||
|
@ -23,6 +23,7 @@ export default abstract class Proxy {
|
||||||
listen = false,
|
listen = false,
|
||||||
autostart = false,
|
autostart = false,
|
||||||
emulateWebsocket = false,
|
emulateWebsocket = false,
|
||||||
|
createDefaultMessage = true,
|
||||||
}: ProxyOptions) {
|
}: ProxyOptions) {
|
||||||
this._swarm = swarm;
|
this._swarm = swarm;
|
||||||
this._protocol = protocol;
|
this._protocol = protocol;
|
||||||
|
@ -35,6 +36,7 @@ export default abstract class Proxy {
|
||||||
onclose,
|
onclose,
|
||||||
onchannel,
|
onchannel,
|
||||||
emulateWebsocket,
|
emulateWebsocket,
|
||||||
|
createDefaultMessage,
|
||||||
};
|
};
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
@ -56,12 +58,14 @@ export default abstract class Proxy {
|
||||||
get protocol(): string {
|
get protocol(): string {
|
||||||
return this._protocol;
|
return this._protocol;
|
||||||
}
|
}
|
||||||
|
public handlePeer({
|
||||||
protected abstract handlePeer({
|
|
||||||
peer,
|
peer,
|
||||||
muxer,
|
muxer,
|
||||||
...options
|
...options
|
||||||
}: DataSocketOptions & PeerOptions);
|
}: DataSocketOptions & PeerOptions) {
|
||||||
|
const conn = new Peer({ proxy: this, peer, muxer, ...options });
|
||||||
|
conn.init();
|
||||||
|
}
|
||||||
|
|
||||||
protected _init() {
|
protected _init() {
|
||||||
// Implement in subclasses
|
// Implement in subclasses
|
||||||
|
|
|
@ -6,7 +6,7 @@ const IPV6 = "IPv6";
|
||||||
|
|
||||||
type AddressFamily = "IPv6" | "IPv4";
|
type AddressFamily = "IPv6" | "IPv4";
|
||||||
|
|
||||||
export interface SocketOptions {
|
interface SocketOptions {
|
||||||
allowHalfOpen?: boolean;
|
allowHalfOpen?: boolean;
|
||||||
remoteAddress?: string;
|
remoteAddress?: string;
|
||||||
remotePort?: number;
|
remotePort?: number;
|
||||||
|
|
Loading…
Reference in New Issue