繁体   English   中英

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

[英]C# Apple Bonjour - how to monitor service records within 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)行。 在不停止解析器的情况下,一切都可以按需进行。 在每次TxtRecord更改时,都会调用ServiceResolved。 但是“为了减轻网络负担”解析器应该停止(否则我们的Windows事件日志会被Bonjour错误所困扰:解析器> 2分钟...)

因此,我查看了Apple常见问题解答,因为我有一个连续的解决方案:

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

不好的是,C#Bonjour Wrapper似乎没有监视接口。

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

好的,让我们测试一下Query函数:

   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,对正确的DNSSDRRType进行了很好的API描述,但TXT似乎是正确的。 但是,如何从中获取TXTRecord对象呢?

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

技术问答QA1306-Apple Developer中解释了TXTRecord格式实际上有两种格式:-(在我们的情况下,我可以用它来从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

但是,我希望不再提供信息,而是希望通过基于事件的监视来支持基于事件的解决方案。 任何想法?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM