@@ -48,9 +48,14 @@ interface ServiceBrowser extends dbus.ClientInterface {
4848 // on(event: 'CacheExhausted', listener: () => void): this;
4949}
5050
51- let cachedServer : Server | undefined ;
51+ type ServerObject = {
52+ proxy : dbus . ProxyObject ;
53+ iface : Server ;
54+ } ;
5255
53- async function getServer ( ) : Promise < Server > {
56+ let cachedServer : ServerObject | undefined ;
57+
58+ async function getServer ( ) : Promise < ServerObject > {
5459 if ( cachedServer === undefined ) {
5560 const bus = dbus . systemBus ( ) ;
5661 // dbus-next will queue messages and wait forever for a connection
@@ -66,9 +71,9 @@ async function getServer(): Promise<Server> {
6671 } ) ;
6772 } ) ;
6873 const proxy = await bus . getProxyObject ( 'org.freedesktop.Avahi' , '/' ) ;
69- const server = proxy . getInterface < Server > ( 'org.freedesktop.Avahi.Server' ) ;
70- const version = await server . GetAPIVersion ( ) ;
71- cachedServer = server ;
74+ const iface = proxy . getInterface < Server > ( 'org.freedesktop.Avahi.Server' ) ;
75+ const version = await iface . GetAPIVersion ( ) ;
76+ cachedServer = { proxy , iface } ;
7277 }
7378
7479 return cachedServer ;
@@ -82,7 +87,7 @@ export async function getInstance(): Promise<dnssd.Client> {
8287class AvahiClient implements dnssd . Client {
8388 private destroyOps = new Array < ( ) => void > ( ) ;
8489
85- constructor ( readonly server : Server ) {
90+ constructor ( public readonly server : ServerObject ) {
8691 }
8792
8893 public createBrowser ( options : dnssd . BrowseOptions ) : Promise < dnssd . Browser > {
@@ -134,18 +139,24 @@ class AvahiBrowser extends events.EventEmitter implements dnssd.Browser {
134139
135140 constructor ( private readonly client : AvahiClient , private options : dnssd . BrowseOptions ) {
136141 super ( ) ;
137- this . bus = ( client . server as any ) . $object . bus ;
142+ // Due to race condition: https://github.com/lathiat/avahi/issues/9
143+ // we have to add signal listeners now before creating browser objects
144+ // otherwise we miss signals.
145+ this . bus = client . server . proxy . bus ;
138146 ( this . bus as any ) . on ( 'message' , ( msg : dbus . Message ) => {
139147 if ( msg . type !== dbus . MessageType . SIGNAL ) {
140148 return ;
141149 }
142150 if ( msg . interface !== 'org.freedesktop.Avahi.ServiceBrowser' ) {
143151 return ;
144152 }
153+ // TODO: should also check msg.path, but we can receive messages
154+ // before ServiceBrowserNew() returns when we don't know the path
155+ // yet.
145156 switch ( msg . member ) {
146157 case 'ItemNew' : {
147158 const [ iface , protocol , name , type , domain , flags ] = msg . body ;
148- client . server . ResolveService ( iface , protocol , name , type , domain , protocol , 0 ) . then (
159+ client . server . iface . ResolveService ( iface , protocol , name , type , domain , protocol , 0 ) . then (
149160 ( [ iface , protocol , name , type , domain , host , aprotocol , addr , port , txt , flags ] ) => {
150161 const service = new AvahiService ( iface , protocol , name , type , domain , host , aprotocol , addr , port , txt , flags ) ;
151162 this . services . push ( service ) ;
@@ -183,7 +194,7 @@ class AvahiBrowser extends events.EventEmitter implements dnssd.Browser {
183194 public async start ( ) : Promise < void > {
184195 const proto = this . options . ipv === 'IPv6' ? PROTO_INET6 : PROTO_INET ;
185196 const type = `_${ this . options . service } ._${ this . options . transport || 'tcp' } ` ;
186- const objPath = await this . client . server . ServiceBrowserNew ( IF_UNSPEC , proto , type , '' , 0 ) ;
197+ const objPath = await this . client . server . iface . ServiceBrowserNew ( IF_UNSPEC , proto , type , '' , 0 ) ;
187198 const proxy = await this . bus . getProxyObject ( 'org.freedesktop.Avahi' , objPath ) ;
188199 this . browser = proxy . getInterface < ServiceBrowser > ( 'org.freedesktop.Avahi.ServiceBrowser' ) ;
189200 }
0 commit comments