@@ -20,7 +20,7 @@ class BonjourClient extends events.EventEmitter implements dnssd.Client {
2020 }
2121 }
2222
23- public browse ( opts : dnssd . BrowseOptions ) : Promise < dnssd . Browser > {
23+ public createBrowser ( opts : dnssd . BrowseOptions ) : Promise < dnssd . Browser > {
2424 const browser = new BonjourBrowser ( this , opts ) ;
2525 return Promise . resolve ( browser ) ;
2626 }
@@ -129,25 +129,50 @@ class BonjourClient extends events.EventEmitter implements dnssd.Client {
129129 }
130130}
131131
132+ /** Per-client browser object. */
133+ type ClientBrowser = {
134+ /** Bonjour client associated with specific network interface and address. */
135+ bClient : bonjour . Bonjour ,
136+ /** Bonjour browser for the Bonjour client. */
137+ browser : bonjour . Browser ,
138+ /** Services discovered by the browser. */
139+ services : BonjourService [ ] ,
140+ /** Update timer - undefined if not started. */
141+ updateInterval ?: NodeJS . Timer ,
142+ } ;
143+
132144class BonjourBrowser extends events . EventEmitter implements dnssd . Browser {
133- private readonly browsers = new Array < {
134- bClient : bonjour . Bonjour ,
135- browser : bonjour . Browser ,
136- services : BonjourService [ ] ,
137- updateInterval : NodeJS . Timer ,
138- } > ( ) ;
145+ private started = false ;
146+ private readonly browsers = new Array < ClientBrowser > ( ) ;
139147
140148 constructor ( private readonly client : BonjourClient , private readonly opts : dnssd . BrowseOptions ) {
141149 super ( ) ;
142- client . on ( 'clientAdded' , c => this . addBrowser ( c ) ) ;
143- client . on ( 'clientRemoved' , c => this . removeBrowser ( c ) ) ;
150+ this . addBrowser = this . addBrowser . bind ( this ) ;
151+ this . removeBrowser = this . removeBrowser . bind ( this ) ;
152+ client . on ( 'clientAdded' , this . addBrowser ) ;
153+ client . on ( 'clientRemoved' , this . removeBrowser ) ;
144154 client . forEachClient ( c => this . addBrowser ( c ) ) ;
145155 }
146156
147- public destroy ( ) : void {
157+ public async start ( ) : Promise < void > {
148158 for ( const b of this . browsers ) {
149- b . browser . stop ( ) ;
159+ this . startClientBrowser ( b ) ;
150160 }
161+ this . started = true ;
162+ }
163+
164+ public async stop ( ) : Promise < void > {
165+ for ( const b of this . browsers ) {
166+ this . stopClientBrowser ( b ) ;
167+ }
168+ this . started = false ;
169+ }
170+
171+ public destroy ( ) : void {
172+ this . removeAllListeners ( ) ;
173+ this . client . off ( 'clientAdded' , this . addBrowser ) ;
174+ this . client . off ( 'clientRemoved' , this . removeBrowser ) ;
175+ this . stop ( ) ;
151176 }
152177
153178 private addBrowser ( bClient : bonjour . Bonjour ) {
@@ -176,24 +201,39 @@ class BonjourBrowser extends events.EventEmitter implements dnssd.Browser {
176201 const [ service ] = services . splice ( index , 1 ) ;
177202 this . emit ( 'removed' , service , false ) ;
178203 } ) ;
179- this . browsers . push ( {
180- bClient : bClient , browser : browser , services : services , updateInterval : setInterval ( ( ) => {
181- // poll again every 1 second
182- browser . update ( ) ;
183- } , 1000 )
184- } ) ;
185- browser . start ( ) ;
204+ const clientBrowser = { bClient : bClient , browser : browser , services : services } ;
205+ this . browsers . push ( clientBrowser ) ;
206+
207+ // If a new client is added after we have already started browsing, we need
208+ // to start that browser as well.
209+ if ( this . started ) {
210+ this . startClientBrowser ( clientBrowser ) ;
211+ }
186212 }
187213
188214 private removeBrowser ( bClient : bonjour . Bonjour ) : void {
189215 const i = this . browsers . findIndex ( v => v . bClient === bClient ) ;
190216 const [ removed ] = this . browsers . splice ( i , 1 ) ;
191- clearInterval ( removed . updateInterval ) ;
192- removed . browser . stop ( ) ;
217+ this . stopClientBrowser ( removed ) ;
193218 for ( const s of removed . services ) {
194219 this . emit ( 'removed' , s ) ;
195220 }
196221 }
222+
223+ private startClientBrowser ( clientBrowser : ClientBrowser ) : void {
224+ clientBrowser . browser . start ( ) ;
225+ clientBrowser . updateInterval = setInterval ( ( ) => {
226+ // poll again every 1 second
227+ clientBrowser . browser . update ( ) ;
228+ } , 1000 ) ;
229+ }
230+
231+ private stopClientBrowser ( clientBrowser : ClientBrowser ) : void {
232+ if ( clientBrowser . updateInterval ) {
233+ clearInterval ( clientBrowser . updateInterval ) ;
234+ clientBrowser . browser . stop ( ) ;
235+ }
236+ }
197237}
198238
199239class BonjourService implements dnssd . Service {
0 commit comments