import debug from "debug" ; import { createSocket , SocketType } from "dgram" ; import { Address } from "./types/model" ; import { findPort } from "./utils" ; const log = debug ( "werift-ice:packages/ice/src/transport.ts" ) ; export class UdpTransport implements Transport { private socket = createSocket ( this . type ) ; onData : ( data : Buffer , addr : Address ) => void = ( ) => { } ; constructor ( private type , private portRange ? ) { this . socket . on ( "message" , ( data , info ) => { if ( info . family === "IPv6" ) { [ info . address ] = info . address . split ( "%" ) ; } try { this . onData ( data , [ info . address , info . port ] ) ; } catch ( error ) { log ( "onData error" , error ) ; } } ) ; } static async init ( type , portRange ? ) { const transport = new UdpTransport ( type , portRange ) ; await transport . init ( ) ; return transport ; } private async init ( ) { if ( this . portRange ) { const port = await findPort ( this . portRange [ 0 ] , this . portRange [ 1 ] , this . type ) ; this . socket . bind ( port ) ; } else { this . socket . bind ( ) ; } await new Promise ( ( r ) => this . socket . once ( "listening" , r ) ) ; } send = ( data , addr ) => new Promise < void > ( ( r , f ) => { this . socket . send ( data , addr [ 1 ] , addr [ 0 ] , ( error ) => { if ( error ) { log ( "send error" , addr , data ) ; f ( error ) ; } else { r ( ) ; } } ) ; } ) ; address ( ) { return this . socket . address ( ) ; } close = ( ) => new Promise < void > ( ( r ) => { this . socket . once ( "close" , r ) ; try { this . socket . close ( ) ; } catch ( error ) { r ( ) ; } } ) ; } export interface Transport { onData : ( data : Buffer , addr : Address ) => void ; send : ( data : Buffer , addr : Address ) => Promise < void > ; }