C#Apple Bonjour-如何在Windows中监控服务记录



我正在使用Apples Bonjour来发音一些客户端信息。

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 ) 
   {
       //... get the information ...
       //
       // Stop the resolve to reduce the burden on the network // <- copied from Apples examples
       //
       m_resolver.Stop(); // (AAAA) <- just a merker ;-)
       m_resolver = null;
   }
}

我修改了源代码以保持简单。

目标:一旦服务的txtRecord发生更改,就会引起注意。

我的实际问题是(AAAA)线。在不停止解析器的情况下,一切都按需工作。每次Txt记录更改时,都会调用ServiceResolved。但是"为了减轻网络负担",解析器应该停止(否则,我们的windows事件日志会因Bonjour错误而被篡改:解析器>2分钟…)

因此,我看了一下苹果的常见问题,因为我有一个连续的解决方案:

有一些罕见的应用程序需要保持Resolve运行,以便监视TXT记录的更改。例如,iChat会持续监控好友状态消息的变化,该消息存储在Bonjour TXT记录中。如果您的应用程序需要此类型的功能,从Mac OS X 10.4开始,您现在可以使用CFNetServiceMonitor和/或[NSNetService startMonitoring]监视TXT记录https://developer.apple.com/library/mac/qa/qa1297/_index.html

糟糕的是,在C#BonjourWrapper中似乎不存在监控接口。

注意:函数DNSServiceQueryRecord将允许您将查询限制为仅TXT记录,这比使用常规Resolve操作发送SRV、TXT和地址记录的查询更有效。

好的,让我们测试一下查询功能:

   public void ServiceResolved( DNSSDService sref, DNSSDFlags flags, uint ifIndex, String serviceName, String hostName, ushort port, TXTRecord txtRecord ) 
   {
       m_resolver.Stop(); 
       m_resolver = null;
       // just to test the 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 to get a TXTRecord-objet of rdata? Using binaryFormatter serializiation fails
      var arrBytes = (Byte[])rdata;
      var txt = System.Text.Encoding.ASCII.GetString( bytes); /es, its the record
   }

Damm,对什么是正确的DNSSRRT类型的API描述很好,但TXT似乎是正确的。但是如何从中获取TXTRecord对象?

有更好的线索吗,如何在服务TxtRecord更改时触发,或者至少如何将rdata转换为有效的TxtRecord对象?

TXTRecord格式在技术问答中有解释;一个QA1306-苹果开发者实际上有两种格式:-(在我们的情况下,我可以使用它从rdata获取有效的TXTRecord:

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 {
        }
    }
}

不幸的是,TXTRecord类似乎有缺陷。

txtRecord.SetValue( "KEY", "VALUE" );
bool b = txtRecord.ContainsKey( "KEY" ); -> returns false

但是,我更喜欢基于事件的解决方案和基于事件的监控,而不是提取信息。知道吗?

最新更新