/// <summary> /// Event GetStatus stub. /// </summary> /// <param name="header">Header object.</param> /// <param name="reader">An XmlReader positioned at the begining of the GetStatus request body element.</param> /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param> /// <returns>Byte array containing an GetStatus response.</returns> /// <remarks>This method is used by the stack framework. Do not use this method.</remarks> public WsMessage GetStatus(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints) { // Parse GetStatus Request /////////////////////////////// // there's no info in GetStatus that we actually need, just get the identifier from header String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); // Iterate the list of hosted services at the specified endpoint and get the status of the first // subscription matching the eventSink. Not pretty but eventing and shared service endpoints don't // fit together if (eventSinkID != null) { // Parse urn:uuid from the To address string endpointAddress = FixToAddress(header.To); DpwsHostedService endpoint = (DpwsHostedService)serviceEndpoints[endpointAddress]; if (endpoint != null) { DpwsWseEventSink eventSink; if ((eventSink = GetEventSink(endpoint.EventSources, eventSinkID)) != null) { long timeRemaining = DateTime.Now.Ticks - (eventSink.StartTime + eventSink.Expires); timeRemaining = timeRemaining < 0 ? 0 : timeRemaining; return(GetStatusResponse(header, timeRemaining)); } } } // Something went wrong throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess); }
// Build an IntegerEvent private String BuildIntegerEventMessage(DpwsHostedService hostedService) { integerEventSerial++; return "<evnt:IntegerEvent xmlns:evnt='" + hostedService.ServiceNamespace.NamespaceURI + "'>" + "<evnt:Param>" + integerEventSerial + "</evnt:Param>" + "</evnt:IntegerEvent>"; }
public static void Main() { // *** Relationship (Services) *** // Set a simple service without any // operations and event as host service DpwsHostedService service1 = new DpwsHostedService(); service1.ServiceTypeName = "SimpleServiceType1"; service1.ServiceNamespace = new WsXmlNamespace("simple1", // prefix "http://schemas.sample.org/SimpleService1"); // namespace URI service1.ServiceID = "urn:uuid:cf16db78-02c9-c8ca-b37b-0000004071f6"; // Set the service as host service Device.Host = service1; // Add a second service as hosted service DpwsHostedService service2 = new DpwsHostedService(); service2.ServiceTypeName = "SimpleServiceType2"; service2.ServiceNamespace = new WsXmlNamespace("simple2", // prefix "http://schemas.sample.org/SimpleService2"); // namespace URI service2.ServiceID = "urn:uuid:ec499d62-02c9-c8ca-b7ee-0000000bf3dd"; // Add the service as hosted service Device.HostedServices.Add(service2); // Let clients identify this device Device.EndpointAddress = "urn:uuid:c5201073-fa27-c8c9-9634-0000001dd159"; // Set this device property if you want to ignore this clients request Device.IgnoreLocalClientRequest = false; // Start the device Device.Start(); // Keep the device alive Thread.Sleep(Timeout.Infinite); }
/// <summary> /// Use this method to raise an event. /// </summary> /// <param name="hostedService">The hosted service that contains the event source.</param> /// <param name="eventSource">The event source that define the event.</param> /// <param name="eventMessage">The event message buffer.</param> /// <remarks> /// A device developer is responsible for building the event message buffer sent /// to clients that have an active event subscription with an event source. The subscription manager /// uses the hosted service parameter to access various properties of the service. The event source /// parameter is used to access the event sinks collection of the event source. Note: This method /// requires special provisions in order to properly build event message headers for each event sink. /// In order to send an event to a listening client the soap.header.To property must be changed for /// each listening client. In the future custom attribute support will solve this problem. For now /// however a search and replace mechanism is used to modifiy the header.To property. When a device /// developer builds the event message buffer they must use the search string WSDNOTIFYTOADDRESS for /// the To header property. /// </remarks> public void FireEvent(DpwsHostedService hostedService, DpwsWseEventSource eventSource, WsMessage msgEvt) { // Find the specified event source if (eventSource == null) { throw new ArgumentNullException(); } DpwsWseEventSinks eventSinks = eventSource.EventSinks; // if there are event sources display message int count = eventSinks.Count; if (count > 0) { System.Ext.Console.Write(""); System.Ext.Console.Write("Firing " + eventSource.Name); System.Ext.Console.Write(""); } // Loop through event sinks and send the event message for (int i = count - 1; i >= 0; i--) { DpwsWseEventSink eventSink = eventSinks[i]; // Try to send event. If attempt fails delete the subscription/eventSink try { msgEvt.Header = new WsWsaHeader(msgEvt.Header.Action, msgEvt.Header.RelatesTo, eventSink.NotifyTo.Address.AbsoluteUri, null, null, eventSink.NotifyTo.RefParameters); SendEvent(msgEvt, eventSink.NotifyTo.Address); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("FireEvent failed. Deleting EventSink! NotifyToAddress = " + eventSink.NotifyTo.Address + " Exception: " + e.Message); System.Ext.Console.Write(""); if (!(e is WebException)) { try { // Send oneway subscription end message SendSubscriptionEnd(eventSink, "DeliveryFailure", hostedService.ServiceID); } catch { } } // Remove event sink from event source list eventSinks.RemoveAt(i); } } }
/// <summary> /// Use this method to raise an event. /// </summary> /// <param name="hostedService">The hosted service that contains the event source.</param> /// <param name="eventSource">The event source that define the event.</param> /// <param name="eventMessage">The event message buffer.</param> /// <remarks> /// A device developer is responsible for building the event message buffer sent /// to clients that have an active event subscription with an event source. The subscription manager /// uses the hosted service parameter to access various properties of the service. The event source /// parameter is used to access the event sinks collection of the event source. Note: This method /// requires special provisions in order to properly build event message headers for each event sink. /// In order to send an event to a listening client the soap.header.To property must be changed for /// each listening client. In the future custom attribute support will solve this problem. For now /// however a search and replace mechanism is used to modifiy the header.To property. When a device /// developer builds the event message buffer they must use the search string WSDNOTIFYTOADDRESS for /// the To header property. /// </remarks> public void FireEvent(DpwsHostedService hostedService, DpwsWseEventSource eventSource, WsMessage msgEvt) { // Find the specified event source if (eventSource == null) throw new ArgumentNullException(); DpwsWseEventSinks eventSinks = eventSource.EventSinks; // if there are event sources display message int count = eventSinks.Count; if (count > 0) { System.Ext.Console.Write(""); System.Ext.Console.Write("Firing " + eventSource.Name); System.Ext.Console.Write(""); } // Loop through event sinks and send the event message for (int i = count-1; i >= 0; i--) { DpwsWseEventSink eventSink = eventSinks[i]; // Try to send event. If attempt fails delete the subscription/eventSink try { msgEvt.Header = new WsWsaHeader(msgEvt.Header.Action, msgEvt.Header.RelatesTo, eventSink.NotifyTo.Address.AbsoluteUri, null, null, eventSink.NotifyTo.RefParameters); SendEvent(msgEvt, eventSink.NotifyTo.Address); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("FireEvent failed. Deleting EventSink! NotifyToAddress = " + eventSink.NotifyTo.Address + " Exception: " + e.Message); System.Ext.Console.Write(""); if (!(e is WebException)) { try { // Send oneway subscription end message SendSubscriptionEnd(eventSink, "DeliveryFailure", hostedService.ServiceID); } catch { } } // Remove event sink from event source list eventSinks.RemoveAt(i); } } }
public static void Main() { // *** Relationship (Services) *** // Set a simple service without any // operations and event as host service DpwsHostedService service1 = new DpwsHostedService(); service1.ServiceTypeName = "SimpleServiceType1"; service1.ServiceNamespace = new WsXmlNamespace("simple1", "http://schemas.sample.org/SimpleService1"); service1.ServiceID = "urn:uuid:cf16db78-02c9-c8ca-b37b-0000004071f6"; // set the service as host service Device.Host = service1; // // Add a second service as hosted service DpwsHostedService service2 = new DpwsHostedService(); service2.ServiceTypeName = "SimpleServiceType2"; service2.ServiceNamespace = new WsXmlNamespace("simple2", "http://schemas.sample.org/SimpleService2"); service2.ServiceID = "urn:uuid:ec499d62-02c9-c8ca-b7ee-0000000bf3dd"; // Add the service as hosted service Device.HostedServices.Add(service2); // Let clients identify this device Device.EndpointAddress = "urn:uuid:bde0943a-0516-c8ca-80a6-000000b525ed"; // Set this device property if you want to ignore this clients request Device.IgnoreLocalClientRequest = false; // Metadata // ThisModel Device.ThisModel.Manufacturer = "Apress, Inc."; Device.ThisModel.ManufacturerUrl = "http://www.apress.com"; Device.ThisModel.ModelName = "MetadataProvidingModel"; Device.ThisModel.ModelNumber = "12345"; Device.ThisModel.ModelUrl = "http://www.apress.com"; Device.ThisModel.PresentationUrl = "http://www.apress.com"; // ThisDevice Device.ThisDevice.FriendlyName = "Describing device that provides metadata"; Device.ThisDevice.FirmwareVersion = "demo"; Device.ThisDevice.SerialNumber = "12345678"; // Start the device Device.Start(); // Keep the device alive Thread.Sleep(Timeout.Infinite); }
/// <summary> /// Method used to expire events and send EndTo notification to an event sink /// </summary> public void EventService(object arg) { DateTime curDateTime = DateTime.Now; try { // Loop through hosted services int servicesCount = Device.HostedServices.Count; for (int i = 0; i < servicesCount; i++) { DpwsHostedService hostedService = (DpwsHostedService)Device.HostedServices[i]; // Loop through event sources int eventSourcesCount = hostedService.EventSources.Count; for (int j = 0; j < eventSourcesCount; j++) { DpwsWseEventSource eventSource = hostedService.EventSources[j]; // Loop through event sinks. Check expiration time. If an event has // expired send subscription end message and delete event sink. int eventSinkCount = eventSource.EventSinks.Count; for (int k = eventSinkCount - 1; k >= 0; k--) { DpwsWseEventSink eventSink = eventSource.EventSinks[k]; // If time has expired delete event sink if (eventSink.StartTime + eventSink.Expires > curDateTime.Ticks) { eventSource.EventSinks.RemoveAt(k); } } } } } catch (Exception e) { System.Ext.Console.Write("Event Queue Manager threw and exception. " + e.Message); } }
public EventSimulator(DpwsHostedService hostedService) { m_hostedService = hostedService; }
public virtual WsMessage ProbeMatch(WsMessage probe, DpwsHostedService matchedService) { XmlReader reader = probe.Reader; WsWsaHeader header = probe.Header; // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build ProbeMatch using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // If a Host exist write the Host namespace WsXmlNamespaces additionalPrefixes = null; if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsWsaHeader matchHeader = new WsWsaHeader( this.Version.DiscoveryNamespace + "/ProbeMatches", // Action header.MessageID, // RelatesTo this.Version.AnonymousUri, // To null, null, null); // ReplyTo, From, Any WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version); smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatches", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatch", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(matchedService == null ? Device.EndpointAddress : matchedService.EndpointAddress); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // Write hosted service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); WriteDeviceServiceTypes(xmlWriter); xmlWriter.WriteEndElement(); // End Types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null); string transport = Device.TransportAddress; if(matchedService != null) { int idx = transport.LastIndexOf('/'); if(idx != -1) { transport = transport.Substring(0, idx + 1); transport += matchedService.EndpointAddress.Substring(matchedService.EndpointAddress.IndexOf("urn:uuid:") + 9); } } int idx2 = transport.ToLower().IndexOf("localhost"); if(idx2 != -1) { transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/); } xmlWriter.WriteString(transport); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null); xmlWriter.WriteString(Device.MetadataVersion.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); smw.WriteSoapMessageEnd(xmlWriter); msg.Body = xmlWriter.ToArray(); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took"); // Delay probe match as per Ws-Discovery specification (2.4 Protocol Assignments) Thread.Sleep(new Random().Next(Device.ProbeMatchDelay)); // Return stream buffer return msg; } }
/// <summary> /// Event renew stub. /// </summary> /// <param name="header">Header object.</param> /// <param name="reader">An XmlReader positioned at the begining of the Renew request body element.</param> /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param> /// <returns>Byte array containing an Renew response.</returns> /// <remarks>This method is used by the stack framework. Do not use this method.</remarks> public WsMessage Renew(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints) { long newExpiration = 0; String eventSinkId = String.Empty; // Parse Renew request //////////////////////////// try { reader.ReadStartElement("Renew", WsWellKnownUri.WseNamespaceUri); if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri)) { newExpiration = new WsDuration(reader.ReadElementString()).DurationInSeconds; if (newExpiration <= 0) { throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime); } } else { // Never Expires newExpiration = -1; } eventSinkId = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); if (eventSinkId == null) { throw new XmlException(); } } catch (XmlException e) { throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString()); } // Parse urn:uuid from the To address string endpointAddress = FixToAddress(header.To); // Iterate the list of hosted services at the specified endpoint and renew each subscription // with and event source that matches the eventSinkID DpwsWseEventSink eventSink; bool eventSinkFound = false; DpwsHostedService endpoint = (DpwsHostedService)serviceEndpoints[endpointAddress]; if (endpoint != null) { if ((eventSink = GetEventSink(endpoint.EventSources, eventSinkId)) != null) { eventSinkFound = true; // Update event sink expires time eventSink.Expires = newExpiration; } } // Generate Response if (eventSinkFound) { return(GetStatusResponse(header, newExpiration)); // It's just like the GetStatus Response } throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess, "Subscription was not found. ID=" + eventSinkId); }
/// <summary> /// Eventing UnSubscribe stub. /// </summary> /// <param name="header">Header object.</param> /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param> /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param> /// <returns>Byte array containing an UnSubscribe response.</returns> /// <remarks>This method is used by the stack framework. Do not use this method.</remarks> public WsMessage Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints) { // Parse Unsubscribe Request /////////////////////////////// // there's no info in Unsubscribe that we actually need, just get the identifier from header String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); bool eventSourceFound = false; if (eventSinkID != null) { // Parse urn:uuid from the To address string endpointAddress = FixToAddress(header.To); // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source // that matches the eventSinkID DpwsHostedService serv = (DpwsHostedService)Device.HostedServices[endpointAddress]; if (serv != null) { DpwsWseEventSources eventSources = serv.EventSources; // Delete Subscription // Look for matching event in hosted services event sources DpwsWseEventSource eventSource; DpwsWseEventSinks eventSinks; DpwsWseEventSink eventSink; int eventSourcesCount = eventSources.Count; int eventSinksCount; for (int i = 0; i < eventSourcesCount; i++) { eventSource = eventSources[i]; eventSinks = eventSource.EventSinks; eventSinksCount = eventSinks.Count; eventSink = eventSinks[eventSinkID]; if (eventSink != null) { eventSourceFound = true; eventSource.EventSinks.Remove(eventSink); } } } if (eventSourceFound) { // Generate Response using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader responseHeader = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse", // Action header.MessageID, // RelatesTo header.ReplyTo.Address.AbsoluteUri, // To null, null, null); WsMessage msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); smw.WriteSoapMessageStart(xmlWriter, msg); smw.WriteSoapMessageEnd(xmlWriter); // Return stream buffer msg.Body = xmlWriter.ToArray(); return(msg); } } } // Something went wrong throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess); }
// Builds Service Types list. This hack is required because service spec writers determined that // more than one service type can live at a single endpoint address. Why you would want to break // the object model and allow this feature is unknown so for now we must hack. private string BuildServiceTypesList(DpwsHostedService service, ArrayList processedEndpointList) { if (processedEndpointList.Contains(service.EndpointAddress)) return null; else processedEndpointList.Add(service.EndpointAddress); int serviceCount = Device.HostedServices.Count; string serviceTypes = null; for (int i = 0; i < serviceCount; ++i) { if (((DpwsHostedService)Device.HostedServices[i]).ServiceTypeName == "Internal") continue; if (service.EndpointAddress == Device.HostedServices[i].EndpointAddress) serviceTypes = serviceTypes + ((serviceTypes == null) ? "" : " ") + ((DpwsHostedService)Device.HostedServices[i]).ServiceNamespace.Prefix + ":" + ((DpwsHostedService)Device.HostedServices[i]).ServiceTypeName; } return serviceTypes; }
// Build a SimpleEvent private String BuildSimpleEventMessage(DpwsHostedService hostedService) { return "<evnt:SimpleEvent xmlns:evnt='" + hostedService.ServiceNamespace.NamespaceURI + "'/>"; }
/// <summary> /// Use this method to raise an event. /// </summary> /// <param name="hostedService">The hosted service that contains the event source.</param> /// <param name="eventSource">The event source that define the event.</param> /// <param name="eventMessage">The event message buffer.</param> /// <remarks> /// A device developer is responsible for building the event message buffer sent /// to clients that have an active event subscription with an event source. The subscription manager /// uses the hosted service parameter to access various properties of the service. The event source /// parameter is used to access the event sinks collection of the event source. Note: This method /// requires special provisions in order to properly build event message headers for each event sink. /// In order to send an event to a listening client the soap.header.To property must be changed for /// each listening client. In the future custom attribute support will solve this problem. For now /// however a search and replace mechanism is used to modifiy the header.To property. When a device /// developer builds the event message buffer they must use the search string WSDNOTIFYTOADDRESS for /// the To header property. /// </remarks> public void FireEvent(DpwsHostedService hostedService, DpwsWseEventSource eventSource, WsWsaHeader eventHeader, String eventMessageBody) { // Find the specified event source if (eventSource == null) throw new ArgumentNullException("FireEvent could not locate specified hosted service"); DpwsWseEventSinks eventSinks = eventSource.EventSinks; // if there are event sources display message int count = eventSinks.Count; if (count > 0) { System.Ext.Console.Write(""); System.Ext.Console.Write("Firing " + eventSource.Name); System.Ext.Console.Write(""); } // Loop through event sinks and send the event message for (int i = 0; i < count; i++) { DpwsWseEventSink eventSink = eventSinks[i]; // Try to send event. If attempt fails delete the subscription/eventSink try { MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader header = new WsWsaHeader(eventHeader.Action, eventHeader.RelatesTo, eventSink.NotifyTo.Address.AbsoluteUri, null, null, eventSink.NotifyTo.RefParameters); WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, null, header, null); if (eventMessageBody != null) xmlWriter.WriteRaw(eventMessageBody); WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); xmlWriter.Flush(); xmlWriter.Close(); SendEvent(soapStream.ToArray(), eventSink.NotifyTo.Address.AbsoluteUri); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("FireEvent failed. Deleting EventSink! NotifyToAddress = " + eventSink.NotifyTo.Address + " Exception: " + e.Message); System.Ext.Console.Write(""); // Send oneway subscription end message try { SendSubscriptionEnd(eventSink, "DeliveryFailure", hostedService.ServiceID); } catch { } // Remove event sink from event source list eventSinks.Remove(eventSink); } } }
/// <summary> /// Use this method to raise an event. /// </summary> /// <param name="hostedService">The hosted service that contains the event source.</param> /// <param name="eventSource">The event source that define the event.</param> /// <param name="eventMessage">The event message buffer.</param> /// <remarks> /// A device developer is responsible for building the event message buffer sent /// to clients that have an active event subscription with an event source. The subscription manager /// uses the hosted service parameter to access various properties of the service. The event source /// parameter is used to access the event sinks collection of the event source. Note: This method /// requires special provisions in order to properly build event message headers for each event sink. /// In order to send an event to a listening client the soap.header.To property must be changed for /// each listening client. In the future custom attribute support will solve this problem. For now /// however a search and replace mechanism is used to modifiy the header.To property. When a device /// developer builds the event message buffer they must use the search string WSDNOTIFYTOADDRESS for /// the To header property. /// </remarks> public void FireEvent(DpwsHostedService hostedService, DpwsWseEventSource eventSource, WsWsaHeader eventHeader, String eventMessageBody) { // Find the specified event source if (eventSource == null) { throw new ArgumentNullException("FireEvent could not locate specified hosted service"); } DpwsWseEventSinks eventSinks = eventSource.EventSinks; // if there are event sources display message int count = eventSinks.Count; if (count > 0) { System.Ext.Console.Write(""); System.Ext.Console.Write("Firing " + eventSource.Name); System.Ext.Console.Write(""); } // Loop through event sinks and send the event message for (int i = 0; i < count; i++) { DpwsWseEventSink eventSink = eventSinks[i]; // Try to send event. If attempt fails delete the subscription/eventSink try { MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader header = new WsWsaHeader(eventHeader.Action, eventHeader.RelatesTo, eventSink.NotifyTo.Address.AbsoluteUri, null, null, eventSink.NotifyTo.RefParameters); WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, null, header, null); if (eventMessageBody != null) { xmlWriter.WriteRaw(eventMessageBody); } WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); xmlWriter.Flush(); xmlWriter.Close(); SendEvent(soapStream.ToArray(), eventSink.NotifyTo.Address.AbsoluteUri); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("FireEvent failed. Deleting EventSink! NotifyToAddress = " + eventSink.NotifyTo.Address + " Exception: " + e.Message); System.Ext.Console.Write(""); // Send oneway subscription end message try { SendSubscriptionEnd(eventSink, "DeliveryFailure", hostedService.ServiceID); } catch { } // Remove event sink from event source list eventSinks.Remove(eventSink); } } }
/// <summary> /// Method used to expire events and send EndTo notification to an event sink /// </summary> public void EventService() { DateTime curDateTime; while (m_requestStop == false) { curDateTime = DateTime.Now; try { // Loop through hosted services int servicesCount = Device.HostedServices.Count; for (int i = 0; i < servicesCount; i++) { if (m_requestStop == true) { break; } DpwsHostedService hostedService = (DpwsHostedService)Device.HostedServices[i]; // Loop through event sources int eventSourcesCount = hostedService.EventSources.Count; for (int j = 0; j < eventSourcesCount; j++) { if (m_requestStop == true) { break; } DpwsWseEventSource eventSource = hostedService.EventSources[j]; // Loop through event sinks. Check expiration time. If an event has // expired send subscription end message and delete event sink. int eventSinkCount = eventSource.EventSinks.Count; for (int k = 0; k < eventSinkCount; k++) { if (m_requestStop == true) { break; } DpwsWseEventSink eventSink = eventSource.EventSinks[k]; // If time has expired delete event sink if (eventSink.StartTime + eventSink.Expires > curDateTime.Ticks) { eventSource.EventSinks.Remove(eventSink); } } } } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Event Queue Manager threw and exception. " + e.Message); System.Ext.Console.Write(""); } Thread.Sleep(5000); } }