public Canceler(mDNS enclosingInstance, ServiceInfo info, object lock_Renamed) { InitBlock(enclosingInstance); this.infos = new ServiceInfo[]{info}; this.lock_Renamed = lock_Renamed; Enclosing_Instance.AddListener(info, new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); }
public ServiceInfoResolver(mDNS enclosingInstance, ServiceInfo info) { InitBlock(enclosingInstance); this.info = info; info.dns = Enclosing_Instance; Enclosing_Instance.AddListener(info, new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); }
/// <summary> Generate a possibly unique name for a service using the information we /// have in the cache. /// /// </summary> /// <returns> returns true, if the name of the service info had to be changed. /// </returns> private bool makeServiceNameUnique(ServiceInfo info) { string originalQualifiedName = info.QualifiedName; long now = (DateTime.Now.Ticks - 621355968000000000) / 10000; bool collision; do { collision = false; // Check for collision in cache for (DNSCache.CacheNode j = cache.find(info.QualifiedName.ToLower()); j != null; j = j.Next) { DNSRecord a = (DNSRecord) j.Value; if ((a.type == DNSConstants.TYPE_SRV) && !a.IsExpired(now)) { Service s = (Service) a; if (s.port != info.port || !s.server.Equals(localHost.Name)) { logger.Debug("makeServiceNameUnique() JmDNS.makeServiceNameUnique srv collision:" + a + " s.server=" + s.server + " " + localHost.Name + " equals:" + (s.server.Equals(localHost.Name))); info.SetName(IncrementName(info.getName())); collision = true; break; } } } // Check for collision with other service infos published by JmDNS object selfService = services[info.QualifiedName.ToLower()]; if (selfService != null && selfService != info) { info.SetName(IncrementName(info.getName())); collision = true; } } while (collision); return !(originalQualifiedName.Equals(info.QualifiedName)); }
/// <summary> Unregister a service. The service should have been registered.</summary> public virtual void UnregisterService(ServiceInfo info) { lock (this) { services.Remove(info.QualifiedName.ToLower()); } info.Cancel(); // Note: We use this lock object to synchronize on it. // Synchronizing on another object (e.g. the ServiceInfo) does // not make sense, because the sole purpose of the lock is to // wait until the canceler has finished. If we synchronized on // the ServiceInfo or on the Canceler, we would block all // accesses to synchronized methods on that object. This is not // what we want! object lock_Renamed = new Object(); new Canceler(this, info, lock_Renamed).start(); // Remind: We get a deadlock here, if the Canceler does not run! try { lock (lock_Renamed) { Monitor.Wait(lock_Renamed); } } catch { // empty } }
/// <summary> Register a service. The service is registered for access by other jmdns clients. /// The name of the service may be changed to make it unique. /// </summary> public virtual void RegisterService(ServiceInfo info) { RegisterServiceType(info.type); // bind the service to this address info.server = localHost.Name; info.addr = localHost.Address; lock (this) { makeServiceNameUnique(info); services[info.QualifiedName.ToLower()] = info; } new Prober(this).start(); logger.Info("registerService() JmDNS registered service as " + info); }
internal virtual void HandleServiceResolved(ServiceInfo info) { IList list = (IList) serviceListeners[info.type.ToLower()]; if (list != null) { ServiceEvent event_Renamed = new ServiceEvent(this, info.type, info.getName(), info); // Iterate on a copy in case listeners will modify it ArrayList listCopy = new ArrayList(list); foreach (IServiceListener listener in listCopy) { listener.ServiceResolved(this, event_Renamed); } } }
/// <summary> Request service information. The information about the service is requested /// and the ServiceListener.resolveService method is called as soon as it is available. /// /// </summary> /// <param name="type">full qualified service type, such as <code>_http._tcp.local.</code> . /// </param> /// <param name="name">unqualified service name, such as <code>foobar</code> . /// </param> /// <param name="timeout">timeout in milliseconds /// </param> public virtual void RequestServiceInfo(string type, string name, int timeout) { RegisterServiceType(type); ServiceInfo info = new ServiceInfo(type, name); new ServiceInfoResolver(this, info).start(); try { long end = (DateTime.Now.Ticks - 621355968000000000) / 10000 + timeout; long delay; lock (info) { while (!info.HasData && (delay = end - (DateTime.Now.Ticks - 621355968000000000) / 10000) > 0) { Monitor.Wait(info, TimeSpan.FromMilliseconds(delay)); } } } catch { // empty } }
/// <summary> Creates a new instance. /// /// </summary> /// <param name="source">the JmDNS instance which originated the event. /// </param> /// <param name="type">the type name of the service. /// </param> /// <param name="name">the instance name of the service. /// </param> /// <param name="info">the service info record, or null if the service could be be resolved. /// </param> public ServiceEvent(mDNS source, string type, string name, ServiceInfo info):base() { this.source = source; this.type = type; this.name = name; this.info = info; }
/// <summary> During recovery we need to duplicate service info to reregister them /// /// </summary> internal ServiceInfo(ServiceInfo info) { InitBlock(); if (info != null) { this.type = info.type; this.name = info.name; this.port = info.port; this.weight = info.weight; this.priority = info.priority; this.text = info.text; } }
public Canceler(mDNS enclosingInstance, ServiceInfo[] infos, object lock_Renamed) { InitBlock(enclosingInstance); this.infos = infos; this.lock_Renamed = lock_Renamed; }