import dgram from "dgram"; import EventEmitter from "eventemitter3"; import { UdpAddress, UdpBindOptions, UdpSocket, UdpSocketEvents, UdpSocketOptions, } from "../transport"; const SEND_BUFFER_SIZE = 262144; const RECV_BUFFER_SIZE = 4194304; export class UdpSocketNode extends EventEmitter implements UdpSocket { private _socket: dgram.Socket; constructor(socket: dgram.Socket) { super(); this._socket = socket; this._socket.on("close", () => this.emit("close")); this._socket.on("listening", () => this.emit("listening")); this._socket.on("error", (err) => this.emit("error", err)); this._socket.on("message", (msg, rinfo) => this.emit("message", msg, rinfo)); } async remoteAddress(): Promise { return this._socket.remoteAddress(); } async localAddress(): Promise { return this._socket.address(); } async addMembership(multicastAddress: string, multicastInterface?: string): Promise { this._socket.addMembership(multicastAddress, multicastInterface); } async bind(options: UdpBindOptions): Promise { await new Promise((resolve, reject) => { this._socket.on("error", reject).bind(options, () => { this._socket.removeListener("error", reject); resolve(); }); }); } async connect(port: number, address?: string): Promise { await new Promise((resolve, reject) => { this._socket.on("error", reject).connect(port, address, () => { this._socket.removeListener("error", reject); resolve(); }); }); } async close(): Promise { await new Promise((resolve) => this._socket.close(resolve)); } async dispose(): Promise { await this.close(); } async dropMembership(multicastAddress: string, multicastInterface?: string): Promise { this._socket.dropMembership(multicastAddress, multicastInterface); } async send( data: Uint8Array, offset: number, length: number, port: number, address: string, ): Promise { await new Promise((resolve, reject) => { this._socket.send(data, offset, length, port, address, (err) => { if (err != undefined) { reject(err); return; } resolve(); }); }); } async setBroadcast(flag: boolean): Promise { this._socket.setBroadcast(flag); } async setMulticastInterface(multicastInterface: string): Promise { this._socket.setMulticastInterface(multicastInterface); } async setMulticastLoopback(flag: boolean): Promise { this._socket.setMulticastLoopback(flag); } async setMulticastTTL(ttl: number): Promise { this._socket.setMulticastTTL(ttl); } static async Create(options?: UdpSocketOptions): Promise { return new UdpSocketNode( dgram.createSocket({ ...{ type: "udp4", reuseAddr: true, sendBufferSize: SEND_BUFFER_SIZE, recvBufferSize: RECV_BUFFER_SIZE, }, ...options, }), ); } }