[英]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.