C# Apple Bonjour - how to monitor service records within Windows -
i'm using apples bonjour pronounce client information.
class bonjourexample { private bonjour.dnssdeventmanager m_eventmanager;; private bonjour.dnssdservice m_service; private bonjour.dnssdservice m_browser; private bonjour.dnssdservice m_resolver; private init() { m_service = new dnssdservice(); m_eventmanager = new dnssdeventmanager(); m_eventmanager.servicefound += new _idnssdevents_servicefoundeventhandler(this.servicefound); m_eventmanager.servicelost += new _idnssdevents_servicelosteventhandler(this.servicelost); m_eventmanager.serviceresolved += new _idnssdevents_serviceresolvedeventhandler(this.serviceresolved); m_eventmanager.queryrecordanswered += new _idnssdevents_queryrecordansweredeventhandler(this.queryanswered); m_eventmanager.operationfailed += new _idnssdevents_operationfailedeventhandler(this.operationfailed); m_bonjourbrowser = m_bonjourservice.browse( 0, 0, "_xyz._tcp", null, m_eventmanager ); } private void servicefound(dnssdservice sref, dnssdflags flags, uint ifindex, string servicename, string regtype, string domain ) { m_resolver = m_service.resolve( 0, ifindex, servicename, regtype, domain, m_eventmanager ) ); } public void servicelost( dnssdservice sref, dnssdflags flags, uint ifindex, string servicename, string regtype, string domain ) { } public void serviceresolved( dnssdservice sref, dnssdflags flags, uint ifindex, string servicename, string hostname, ushort port, txtrecord txtrecord ) { //... information ... // // stop resolve reduce burden on network // <- copied apples examples // m_resolver.stop(); // (aaaa) <- merker ;-) m_resolver = null; } }
i modiified source code keep things simple.
goal: noticed txtrecord of service changes.
my actual problem (aaaa) line. without stopping resolver works wanted. @ every txtrecord change serviceresolved called. "to reduce burden on network" resolver shall stopped (otherwise our windows event log flodded bonjour errors: resolver > 2 min...)
thus took @ apples faqs, because continous solution:
there rare applications need keep resolve running in order monitor txt record changes. ichat, example, continuously monitors changes buddy's status message, stored in bonjour txt record. if application requires type of functionality, starting in mac os x 10.4 can monitor txt records using cfnetservicemonitor and/or [nsnetservice startmonitoring] https://developer.apple.com/library/mac/qa/qa1297/_index.html
bad thing there not seem exist monitoring interface @ c# bonjour wrapper.
note: function dnsservicequeryrecord allow restrict query txt records, more efficient using regular resolve operations send query srv, txt , address records.
okay, let's test query function:
public void serviceresolved( dnssdservice sref, dnssdflags flags, uint ifindex, string servicename, string hostname, ushort port, txtrecord txtrecord ) { m_resolver.stop(); m_resolver = null; // test query interface: m_service.queryrecord( 0, 0, servicename, dnssdrrtype.kdnssdtype_txt, dnssdrrclass.kdnssdclass_in, m_bonjoureventmanager ) ); } public void queryrecordanswered( dnssdservice service, dnssdflags flags, uint ifindex, string fullname, dnssdrrtype rrtype, dnssdrrclass rrclass, object rdata, uint ttl ) { // damm, how txtrecord-objet of rdata? using binaryformatter serializiation fails var arrbytes = (byte[])rdata; var txt = system.text.encoding.ascii.getstring( bytes); /es, record }
damm, api-description of what's correct dnssdrrtype, txt seems right one. how txtrecord object out of it?
any better clue, how triggered @ service txtrecord change or @ least how convert rdata vaild txtrecord object?
the txtrecord format explained in technical q&a qa1306 - apple developer there 2 formats :-( in our case can use getting valid txtrecord rdata:
public void queryrecordanswered( dnssdservice service, dnssdflags flags, uint ifindex, string fullname, dnssdrrtype rrtype, dnssdrrclass rrclass, object rdata, uint ttl ) { if( rdata != null ) { try { var bytes = (byte[])rdata; txtrecord txtrecord = new txtrecord(); for( int index = 0; index < bytes.length; ) { int32 length = bytes[index]; string text = system.text.encoding.ascii.getstring( bytes, index+1, length ); string[] keyvalue = text.split( new char[] { '=' }, 2 ); if( keyvalue.length == 2 ) { txtrecord.setvalue( keyvalue[0], keyvalue[1] ); } index += 1 + length; } } catch { } } }
unfortunately txtrecord class seems buggy.
txtrecord.setvalue( "key", "value" ); bool b = txtrecord.containskey( "key" ); -> returns false
but instead of pullung information, i'd favor event based solution event based monitoring. idea?
Comments
Post a Comment