public MFTestResults TransportTest2_DpwsHttpClient() { /// <summary> /// 1. Verifies each of the proerties of a DpwsHttpClient object /// 2. Sets and re-verifies. /// </summary> /// bool testResult = true; try { WsHttpClient testDHC = new WsHttpClient(new ProtocolVersion10()); Random random = new Random(); int timeout = random.Next(10000); Log.Comment("ReceiveTimeout"); if (testDHC.ReceiveTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("ReceiveTimeout wrong type"); testDHC.ReceiveTimeout = timeout; if (testDHC.ReceiveTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("ReceiveTimeout wrong type after set to new"); if (testDHC.ReceiveTimeout != timeout) throw new Exception("ReceiveTimeout wrong data after set to new"); Log.Comment("SendTimeout"); timeout = random.Next(10000); if (testDHC.SendTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("SendTimeout wrong type"); testDHC.SendTimeout = timeout; if (testDHC.SendTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("SendTimeout wrong type after set to new"); if (testDHC.SendTimeout != timeout) throw new Exception("SendTimeout wrong data after set to new"); } catch (Exception e) { testResult = false; Log.Comment("Incorrect exception caught: " + e.Message); } return (testResult ? MFTestResults.Pass : MFTestResults.Fail); }
public MFTestResults TransportTest_HTTP_WsHttpClient() { /// <summary> /// 1. Gets and verifies each of the properties of a WsHttpClient object /// 2. Sets and re-verifies all properties /// </summary> /// bool testResult = true; try { WsHttpClient testWHC = new WsHttpClient(new ProtocolVersion10()); Log.Comment("SendTimeout"); if (testWHC.SendTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("SendTimeout wrong type"); testWHC.SendTimeout = 100; if (testWHC.SendTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("SendTimeout wrong type"); if (testWHC.SendTimeout != 100) throw new Exception("SendTimeout wrong data"); Log.Comment("ReceiveTimeout"); if (testWHC.ReceiveTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("ReceiveTimeout wrong type"); testWHC.ReceiveTimeout = 500; if (testWHC.ReceiveTimeout.GetType() != Type.GetType("System.Int32")) throw new Exception("ReceiveTimeout wrong type"); if (testWHC.ReceiveTimeout != 500) throw new Exception("ReceiveTimeout wrong data"); } catch (Exception e) { testResult = false; Log.Comment("Incorrect exception caught: " + e.Message); } return (testResult ? MFTestResults.Pass : MFTestResults.Fail); }
/// <summary> /// Sends a directed Resolve request and parses ResolveMatch response. /// </summary> /// <param name="endpointAddress"> /// A string containing a Dpws devices transport endpoint address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="serviceAddress"> /// A string containing the address of a service that will handle the resolve request. /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="targetServiceAddress"> /// A string containing the address of a service that can process the resolve request. /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <remarks> /// A Resolve is used to resolve the transport address of a know service. The request contains a service /// address aquired from configuration or a previous Resolve or Metadata Get request. /// The DirectedResolve method sends a Http request to the specified endpoint address. /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches /// response back to the client that made the request. /// </remarks> /// <returns> /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used /// used to locate the actual service on a network and the types supported by the service. /// </returns> public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress) { String messageID = ""; WsMessage resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID); if (resolveRequest == null) return null; System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Resolve:"); System.Ext.Console.Write(resolveRequest.Body as byte[]); // Create an http client and send the resolve request. Use a WspHttpClient to get an array response. WsHttpClient httpClient = new WsHttpClient(m_version); WsMessage resolveResponse = httpClient.SendRequest(resolveRequest, new Uri(endpointAddress)); DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); DpwsServiceDescription resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null); return resolveMatch; }
/// <summary> /// Sends a directed Probe request and parses ProbeMatches responses. /// </summary> /// <param name="endpointAddress"> /// A string containing a Dpws devices transport endpoint address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="targetServiceAddress"> /// A string containing the target service address to probe for. /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="filters"> /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match. /// Null = any type. /// </param> /// <remarks> /// A directed Probe is used to discover services on a network. The DirectedProbe method sends a /// HTTP request to the service specified endpointAddress parameter. A service at the endpoint that /// implements matching types specified in the filters parameter should respond with a ProbeMatches /// message. The ProbeMatches mesgage is returned as the response to the DirectedProbe request. /// If a null filter is supplied any Dpws complient service should reply with a ProbeMatches reponse. /// This method is used to directly ask for service endpoint information. /// </remarks> /// <returns> /// A collection of ProbeMatches objects. A ProbeMatch object contains endpoint details used /// used to locate the actual service on a network and the types supported by the service. /// </returns> /// <exception cref="InvalidOperationException">If a fault response is received.</exception> public DpwsServiceDescriptions DirectedProbe(string endpointAddress, string targetServiceAddress, DpwsServiceTypes filters) { // Build the probe request message string messageID = null; WsMessage probeRequest = BuildProbeRequest(targetServiceAddress, filters, out messageID); System.Ext.Console.Write(""); System.Ext.Console.Write("Sending DirectedProbe:"); System.Ext.Console.Write(probeRequest.Body as byte[]); System.Ext.Console.Write(""); // Create an http client and send the probe request. Use a WspHttpClient to get an array response. WsHttpClient httpClient = new WsHttpClient(m_version); WsMessage probeResponse = httpClient.SendRequest(probeRequest, new Uri(endpointAddress)); // Build probe matches collection DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions(); DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); if (probeResponse != null) { System.Ext.Console.Write(""); System.Ext.Console.Write("ProbeMatches Response From: " + endpointAddress); System.Ext.Console.Write(probeResponse.Body as byte[]); try { DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(probeResponse, messageID, null, null); if (tempMatches != null) { int count = tempMatches.Count; for (int i = 0; i < count; i++) { probeMatches.Add(tempMatches[i]); } } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); } } if (probeMatches.Count == 0) return null; else return probeMatches; }
void SimpleServiceClient_HelloEvent(object obj, DpwsServiceDescription helloEventArgs) { m_receivedHelloEvent = true; DpwsMetadata m_mexDetails = null; try { // Print Hello information //Log.Comment(""); //Log.Comment("SimpleService received a hello request."); ////Log.Comment("Endpoint address: " + helloEventArgs.Endpoint.Address.AbsoluteUri); string types = ""; int count = helloEventArgs.ServiceTypes.Count; for (int i = 0; i < count; i++) { DpwsServiceType type = helloEventArgs.ServiceTypes[i]; types += "NamespaceUri: " + type.NamespaceUri + " " + "TypeName: " + type.TypeName + "\n"; } ////Log.Comment("Types: " + types); if (helloEventArgs.XAddrs != null) { foreach (String xaddr in helloEventArgs.XAddrs) { ////Log.Comment("Xaddrs: " + xaddr); } } ////Log.Comment("Metadata version: " + helloEventArgs.MetadataVersion); ////Log.Comment(""); // Probe for services. For each valid probe match, print service information. DpwsServiceType searchType = new DpwsServiceType("SimpleService", "http://schemas.example.org/SimpleService"); DpwsServiceTypes searchTypes = new DpwsServiceTypes(); searchTypes.Add(searchType); // Accept the first 10 found within the first 10 seconds DpwsServiceDescriptions probeMatches = this.DiscoveryClient.Probe(searchTypes, 1, 10000); // retry if (probeMatches.Count == 0) { probeMatches = this.DiscoveryClient.Probe(searchTypes, 1, 10000); } if (probeMatches != null) { // Print the probe match information ////Log.Comment("**********************"); ////Log.Comment("ProbeMatches received: " + probeMatches.Count); int probeMatchCount = probeMatches.Count; for (int i = 0; i < probeMatchCount; i++) { DpwsServiceDescription probeMatch = probeMatches[i]; ////Log.Comment(""); ////Log.Comment("ProbeMatch:"); ////Log.Comment(" Endpoint Address = " + probeMatch.Endpoint.Address.AbsoluteUri); ////Log.Comment(" Types:"); PrintServiceTypes(probeMatch.ServiceTypes); //////Log.Comment(" Xaddrs:"); //foreach (string xaddr in probeMatch.XAddrs) // //Log.Comment(" TransportAddress = " + xaddr); ////Log.Comment(" Metadata Version = " + probeMatch.MetadataVersion); // Resolve this endpoint DpwsServiceDescription resolveMatch = this.DiscoveryClient.Resolve(probeMatch.Endpoint.Address.AbsoluteUri, 10000); if (resolveMatch != null) { // Print resolve match information ////Log.Comment(""); ////Log.Comment("ResolveMatch:"); ////Log.Comment(" Endpoint Address = " + resolveMatch.Endpoint.Address.AbsoluteUri); ////Log.Comment(" Types:"); PrintServiceTypes(resolveMatch.ServiceTypes); ////Log.Comment(" Xaddrs:"); //foreach (string xaddr in resolveMatch.XAddrs) // //Log.Comment(" TransportAddress = " + xaddr); //Log.Comment(" Metadata Version = " + resolveMatch.MetadataVersion); // For each Xaddr, get metadata foreach (string xaddr in resolveMatch.XAddrs) { // Call Get m_mexDetails = this.MexClient.Get(xaddr); if (m_mexDetails == null) { ////Log.Comment("Get failed. Address: " + xaddr); } else { m_getMex = true; // Display metadata information ////Log.Comment(" Metadata:"); ////Log.Comment(" ThisModel:"); ////Log.Comment(" Manufacturer: " + m_mexDetails.ThisModel.Manufacturer); ////Log.Comment(" ManufacturerUrl: " + m_mexDetails.ThisModel.ManufacturerUrl); ////Log.Comment(" ModelName: " + m_mexDetails.ThisModel.ModelName); ////Log.Comment(" ModelNumber: " + m_mexDetails.ThisModel.ModelNumber); ////Log.Comment(" ModelUrl: " + m_mexDetails.ThisModel.ModelUrl); ////Log.Comment(" PresentationUrl: " + m_mexDetails.ThisModel.PresentationUrl); ////Log.Comment(" ThisDevice:"); ////Log.Comment(" FirmwareVersion: " + m_mexDetails.ThisDevice.FirmwareVersion); ////Log.Comment(" FriendlyName: " + m_mexDetails.ThisDevice.FriendlyName); ////Log.Comment(" SerialNumber: " + m_mexDetails.ThisDevice.SerialNumber); if (m_mexDetails.Relationship.Host != null) { ////Log.Comment(" Host:"); ////Log.Comment(" Service ID: " + m_mexDetails.Relationship.Host.ServiceID); ////Log.Comment(" Address: " + m_mexDetails.Relationship.Host.EndpointRefs[0].Address.AbsoluteUri); ////Log.Comment(" Types:"); PrintServiceTypes(m_mexDetails.Relationship.Host.ServiceTypes); } if (m_mexDetails.Relationship.HostedServices != null) { ////Log.Comment(" HostedServices:"); int hostedServiceCount = m_mexDetails.Relationship.HostedServices.Count; for (int j = 0; j < hostedServiceCount; j++) { DpwsMexService hostedService = m_mexDetails.Relationship.HostedServices[j]; ////Log.Comment(" Service ID: " + hostedService.ServiceID); ////Log.Comment(" Address: " + hostedService.EndpointRefs[0].Address.AbsoluteUri); ////Log.Comment(" Types:"); PrintServiceTypes(hostedService.ServiceTypes); } } } } if (m_mexDetails != null) { // Look for the SimpleService in the HostedServices collection, create an HTTP // client, call TwoWayRequest on the service endpoint, and display the result. int hostedServiceCount = m_mexDetails.Relationship.HostedServices.Count; for (int j = 0; j < hostedServiceCount; j++) { DpwsMexService hostedService = m_mexDetails.Relationship.HostedServices[j]; if (hostedService.ServiceTypes["SimpleService"] != null) // found a SimpleService endpoint { string endpointAddress = hostedService.EndpointRefs[0].Address.AbsoluteUri; ////Log.Comment(""); ////Log.Comment("Calling TwoWayRequest at endpoint: " + endpointAddress); // Create HttpClient and send request int x = 150; int y = 180; byte[] TwoWayRequest = Build2wayRequest(x, y, endpointAddress); //Log.Comment(new String(System.Text.Encoding.UTF8.GetChars(TwoWayRequest))); //DpwsHttpClient httpClient = new DpwsHttpClient(); //DpwsSoapResponse response = httpClient.SendRequest(TwoWayRequest, endpointAddress, false, false); WsHttpClient httpClient = new WsHttpClient(m_version); WsMessage response = httpClient.SendRequest(new WsMessage(null, TwoWayRequest, WsPrefix.Wsdp), new Uri(endpointAddress)); if (response != null) // got a response { try { int sum = Parse2WayResponse(response.Header, response.Reader); //Log.Comment(""); //Log.Comment("Received sum of " + sum.ToString() + " from " + endpointAddress); if ((x + y) == sum) m_twoWay = true; } finally { response.Reader.Close(); } } } } } //Log.Comment(""); } } } } finally { } if (m_mexDetails != null) { arHello.Set(); } }
/// <summary> /// Creates an instance of an DpwsHttpClient class. /// </summary> public DpwsHttpClient() { m_httpClient = new WsHttpClient(); }
/// <summary> /// Use to get the status of an event subscription. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscriptionID"> /// A subscription ID returned from a previous subscribe response. The device uses this ID /// to identify a specific event source subscription. /// </param> /// <returns> /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite. /// </returns> public WsDuration GetStatus(Uri endpointAddress, string subscriptionID) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Renew request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(WsNamespacePrefix.Wse, "Identifier", null, subscriptionID)); WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/GetStatus", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To null, null, nodeList); // ReplyTo, From, Any WsMessage msg = new WsMessage(header, null, WsPrefix.Wse, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Body", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "GetStatus", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End GetStatus // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took"); // Create an Http client and send GetStatus request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToString(); WsMessage getStatusResponse = httpClient.SendRequest(msg, endpointAddress); // If a GetStatus response is received validate the messageID and action and get the remaining // event subscription time. If a fault is received print exception and go on. if (getStatusResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew response is null."); return null; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(getStatusResponse.Body as byte[]); // Note: Since the response is the same for GetStatus ans it is for Renew reuse the // Renew response parser. try { return ProcessRenewResponse((byte[])getStatusResponse.Body, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); } } } return null; }
/// <summary> /// Use to unsubscribe from a devices event source. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscription">An event subscription returned from a previous subscribe call. /// The subscription contains among other things a subscription ID used by the subscription manager /// to identify a specific event source subscription and the endpoint address of the subscription manager. /// </param> /// <returns>True if the Unsubscribe request was successful.</returns> public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Unsubscribe Request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID)); WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Unsubscribe", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To m_version.AddressingNamespace, // ReplyTo subscription.SubscriptionManager.Address.AbsoluteUri, // From nodeList); // Identifier WsMessage msg = new WsMessage(header, null, WsPrefix.Wse, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Unsubscribe", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End Unsubscribe // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Unsubscribe Message Build Took"); // Create an Http client and send Unsubscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); WsMessage unsubscribeResponse = httpClient.SendRequest(msg, endpointAddress); // If a unsubscribe response is received simple validate that the messageID and action are correct and // If a parsing fault is received print exception and go on. if (unsubscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response is null."); return false; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(unsubscribeResponse.Body as byte[]); try { return ProcessUnsubscribeResponse((byte[])unsubscribeResponse.Body, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); return false; } } } }
/// <summary> /// Use to subscribe to a devices, hosted service event sources. /// </summary> /// <param name="subscriptionRequest"> /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event, /// the address where the event is sent, an optional address where subscription end messages are sent, /// A subscription expiration (in duration format) and an optional user defined identifier. /// </param> /// <returns> /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription /// expires (duration) and optional reference parameters and properties. Per spec the /// sub mananger may assign a different duration value than that specified in the request. /// </returns> /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception> public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest) { if ((subscriptionRequest.SubscriptionType == null) || (subscriptionRequest.SubscriptionType.TypeName == null) || (subscriptionRequest.SubscriptionType.NamespaceUri == null) || (subscriptionRequest.EndpointAddress == null) || (subscriptionRequest.NotifyTo == null) || (subscriptionRequest.NotifyTo.Address == null)) { throw new ArgumentNullException(); } // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = subscriptionRequest.EndpointAddress; if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); WsMessage subscribeResponse = null; // Build Subscribe Request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Subscribe", // Action null, // RelatesTo serviceUri.AbsoluteUri, // To m_version.AnonymousUri, // ReplyTo null, null); // From, Any WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri)); WsMessage msg = new WsMessage(header, null, WsPrefix.Wsd | WsPrefix.Wse, additionalPrefixes, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Subscribe", null); // If EndTo is set write it if (subscriptionRequest.EndTo != null) WriteEndpointRef(xmlWriter, subscriptionRequest.EndTo, "EndTo"); // Add the delivery element and NotifyTo endpoint xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Delivery", null); xmlWriter.WriteAttributeString("Mode", m_version.EventingNamespace + "/DeliveryModes/Push"); // Writer the notify to endpoint WriteEndpointRef(xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo"); xmlWriter.WriteEndElement(); // End Delivery // Write Expiration time if (subscriptionRequest.Expires != null) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null); xmlWriter.WriteString(subscriptionRequest.Expires.DurationString); xmlWriter.WriteEndElement(); // End Expires } // Write Filter element specifying the event to subscribe to. xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Filter", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Action"); xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName); xmlWriter.WriteEndElement(); // End Filter xmlWriter.WriteEndElement(); // End Subscribe smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took"); // Create an Http client and send Subscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); subscribeResponse = httpClient.SendRequest(msg, subscriptionRequest.EndpointAddress); // If a subscribe response is received process it and return expiration time the subscription manager // actually assigned. // If a parsing fault is received print exception and go on. DpwsEventSubscription response = null; if (subscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscribe response is null."); return null; } else { byte[] responseBytes = subscribeResponse.Body as byte[]; // It is ok for the service to return a 202 and a 0 length response // if thi is the case just return null if(responseBytes == null || responseBytes.Length == 0) return null; System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host); System.Ext.Console.Write(responseBytes); try { response = ProcessSubscribeResponse(responseBytes, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscription response parsing failed."); System.Ext.Console.Write(e.Message); } } return response; } }
/// <summary> /// Use to get the status of an event subscription. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscriptionID"> /// A subscription ID returned from a previous subscribe response. The device uses this ID /// to identify a specific event source subscription. /// </param> /// <returns> /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite. /// </returns> public WsDuration GetStatus(Uri endpointAddress, string subscriptionID) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Renew request MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode("wse", "Identifier", null, subscriptionID)); WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/GetStatus", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To null, null, nodeList); // ReplyTo, From, Any String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, null, header, null); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement("soap", "Body", null); xmlWriter.WriteStartElement("wse", "GetStatus", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End GetStatus // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took"); // Flush and close writer xmlWriter.Flush(); xmlWriter.Close(); // Create an Http client and send GetStatus request WsHttpClient httpClient = new WsHttpClient(); byte[] getStatusResponse = null; try { getStatusResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("GetStatus failed. " + e.Message); return null; } // If a GetStatus response is received validate the messageID and action and get the remaining // event subscription time. If a fault is received print exception and go on. if (getStatusResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew response is null."); return null; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getStatusResponse))); // Note: Since the response is the same for GetStatus ans it is for Renew reuse the // Renew response parser. try { return ProcessRenewResponse(getStatusResponse, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); } } return null; }
/// <summary> /// Use to unsubscribe from a devices event source. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscription">An event subscription returned from a previous subscribe call. /// The subscription contains among other things a subscription ID used by the subscription manager /// to identify a specific event source subscription and the endpoint address of the subscription manager. /// </param> /// <returns>True if the Unsubscribe request was successful.</returns> public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Unsubscribe Request MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID)); WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/Unsubscribe", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To WsWellKnownUri.WsaAnonymousUri, // ReplyTo subscription.SubscriptionManager.Address.AbsoluteUri, // From nodeList); // Identifier String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, null, header, null); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement("wse", "Unsubscribe", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End Unsubscribe // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Unsubscribe Message Build Took"); // Flush and close writer xmlWriter.Flush(); xmlWriter.Close(); // Create an Http client and send Unsubscribe request WsHttpClient httpClient = new WsHttpClient(); byte[] unsubscribeResponse = null; try { unsubscribeResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe failed. " + e.Message); return false; } // If a unsubscribe response is received simple validate that the messageID and action are correct and // If a parsing fault is received print exception and go on. if (unsubscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response is null."); return false; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(unsubscribeResponse))); try { return ProcessUnsubscribeResponse(unsubscribeResponse, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); return false; } } }
/// <summary> /// Use to subscribe to a devices, hosted service event sources. /// </summary> /// <param name="subscriptionRequest"> /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event, /// the address where the event is sent, an optional address where subscription end messages are sent, /// A subscription expiration (in duration format) and an optional user defined identifier. /// </param> /// <returns> /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription /// expires (duration) and optional reference parameters and properties. Per spec the /// sub mananger may assign a different duration value than that specified in the request. /// </returns> /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception> public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest) { if (subscriptionRequest.SubscriptionType == null) throw new ArgumentNullException("Subscribe - SubscriptionType must not be null"); if (subscriptionRequest.SubscriptionType.TypeName == null) throw new ArgumentNullException("Subscribe - SubscriptionType.TypeName must not be null"); if (subscriptionRequest.SubscriptionType.NamespaceUri == null) throw new ArgumentNullException("Subscribe - SubscriptionType.NamespaceUri must not be null"); if (subscriptionRequest.EndpointAddress == null) throw new ArgumentNullException("Subscribe - EndpointAddress property must not be null."); if (subscriptionRequest.NotifyTo == null) throw new ArgumentNullException("Subscribe - NotifyTo must not be null."); if (subscriptionRequest.NotifyTo.Address == null) throw new ArgumentNullException("Subscribe - NotifyTo.Address must not be null."); // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = subscriptionRequest.EndpointAddress; if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Subscribe Request MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/Subscribe", // Action null, // RelatesTo serviceUri.AbsoluteUri, // To WsWellKnownUri.WsaAnonymousUri, // ReplyTo null, null); // From, Any WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri)); String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wse, additionalPrefixes, header, null); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement("wse", "Subscribe", null); // If EndTo is set write it if (subscriptionRequest.EndTo != null) WriteEndpointRef(ref xmlWriter, subscriptionRequest.EndTo, "EndTo"); // Add the delivery element and NotifyTo endpoint xmlWriter.WriteStartElement("wse", "Delivery", null); xmlWriter.WriteAttributeString("Mode", "http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push"); // Writer the notify to endpoint WriteEndpointRef(ref xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo"); xmlWriter.WriteEndElement(); // End Delivery // Write Expiration time if (subscriptionRequest.Expires != null) { xmlWriter.WriteStartElement("wse", "Expires", null); xmlWriter.WriteString(subscriptionRequest.Expires.DurationString); xmlWriter.WriteEndElement(); // End Expires } // Write Filter element specifying the event to subscribe to. xmlWriter.WriteStartElement("wse", "Filter", null); xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/Action"); xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName); xmlWriter.WriteEndElement(); // End Filter xmlWriter.WriteEndElement(); // End Subscribe WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took"); // Flush and close writer xmlWriter.Flush(); xmlWriter.Close(); // Create an Http client and send Subscribe request WsHttpClient httpClient = new WsHttpClient(); byte[] subscribeResponse = null; try { subscribeResponse = httpClient.SendRequest(soapStream.ToArray(), subscriptionRequest.EndpointAddress.AbsoluteUri, false, false); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscribe failed. " + e.Message); return null; } // If a subscribe response is received process it and return expiration time the subscription manager // actually assigned. // If a parsing fault is received print exception and go on. DpwsEventSubscription response = null; if (subscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscribe response is null."); return null; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host); System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(subscribeResponse))); try { // It is ok for the service to return a 202 and a 0 length response // if thi is the case just return null if (subscribeResponse.Length == 0) return null; response = ProcessSubscribeResponse(subscribeResponse, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscription response parsing failed."); System.Ext.Console.Write(e.Message); } } return response; }
/// <summary> /// Use to request metadata from a devices hosted service endpoint. /// </summary> /// <param name="serviceAddress"> /// A string containing the transport address of a service endpoint. For Dpws the address represents /// a devices transport address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <returns> /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device. /// </returns> public DpwsMetadata Get(string serviceAddress) { // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = new Uri(serviceAddress); if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Get Request MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WstNamespaceUri + "/Get", // Action null, // RelatesTo "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To WsWellKnownUri.WsaAnonymousUri, // ReplyTo null, null); // From, Any String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.None, null, header, null); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took"); // Flush and close writer xmlWriter.Flush(); xmlWriter.Close(); // Create an Http client and send Get request WsHttpClient httpClient = new WsHttpClient(); byte[] getResponse = null; try { System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Get to: " + serviceAddress); getResponse = httpClient.SendRequest(soapStream.ToArray(), serviceAddress, false, false); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Get failed. " + e.Message); return null; } // If a get response is received process it and return DpwsMetadata object DpwsMetadata metadata = null; if (getResponse == null) return null; else { System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getResponse))); System.Ext.Console.Write(""); DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(); try { metadata = soapProcessor.ProcessGetResponse(getResponse, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Get response parser threw an exception. " + e.Message); return null; } } return metadata; }
/// <summary> /// Use to request metadata from a devices hosted service endpoint. /// </summary> /// <param name="serviceAddress"> /// A string containing the transport address of a service endpoint. For Dpws the address represents /// a devices transport address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <returns> /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device. /// </returns> public DpwsMetadata Get(string serviceAddress) { // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = new Uri(serviceAddress); if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Get Request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WstNamespaceUri + "/Get", // Action null, // RelatesTo "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To //TODO: should be ROLE??? m_version.AnonymousRoleUri, // ReplyTo null, null); // From, Any WsMessage msg = new WsMessage(header, null, WsPrefix.None, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took"); // Create an Http client and send Get request WsHttpClient httpClient = new WsHttpClient(m_version); System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Get to: " + serviceAddress); msg.Body = xmlWriter.ToArray(); WsMessage getResponse = httpClient.SendRequest(msg, new Uri(serviceAddress)); // If a get response is received process it and return DpwsMetadata object DpwsMetadata metadata = null; if (getResponse == null || getResponse.Body == null) { return null; } else { DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); try { System.Ext.Console.Write(getResponse.Body as byte[]); System.Ext.Console.Write(""); metadata = soapProcessor.ProcessGetResponse((byte[])getResponse.Body, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Get response parser threw an exception. " + e.Message); return null; } } return metadata; } }
/// <summary> /// Sends a directed Resolve request and parses ResolveMatch response. /// </summary> /// <param name="endpointAddress"> /// A string containing a Dpws devices transport endpoint address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="serviceAddress"> /// A string containing the address of a service that will handle the resolve request. /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="targetServiceAddress"> /// A string containing the address of a service that can process the resolve request. /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <remarks> /// A Resolve is used to resolve the transport address of a know service. The request contains a service /// address aquired from configuration or a previous Resolve or Metadata Get request. /// The DirectedResolve method sends a Http request to the specified endpoint address. /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches /// response back to the client that made the request. /// </remarks> /// <returns> /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used /// used to locate the actual service on a network and the types supported by the service. /// </returns> public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress) { String messageID = ""; byte[] resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID); if (resolveRequest == null) return null; System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Resolve:"); System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(resolveRequest))); // Create an http client and send the resolve request. Use a WspHttpClient to get an array response. WsHttpClient httpClient = new WsHttpClient(); byte[] resolveResponse = httpClient.SendRequest(resolveRequest, endpointAddress, false, false); DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(); DpwsServiceDescription resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null); return resolveMatch; }
/// <summary> /// Used by the subscription manager to send a subscription end message to a listening client. /// </summary> /// <param name="eventSink">An event sink object containing the client endpoint information.</param> /// <param name="subEndType">A string that specifies the reason fot the subscription end.</param> /// <param name="subMangerID">A id used by the client to identify this subcription.</param> /// <remarks>If an error occures when sending an event message this method is called to tell /// the client this subscription has been expired. /// </remarks> private void SendSubscriptionEnd(DpwsWseEventSink eventSink, string subEndType, string subMangerID) { // if we weren't given an EndTo, don't send if (eventSink.EndTo == null) { return; } // Parse the http transport address if (eventSink.EndTo.Address.Scheme == "http") { WsHttpClient httpClient = new WsHttpClient(); httpClient.SendRequest(SubscriptionEndResponse(eventSink, subEndType, subMangerID), eventSink.EndTo.Address.AbsoluteUri, true, false); } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsupported transport address Subscription EndTo.Address: " + eventSink.EndTo.Address); System.Ext.Console.Write(""); return; } }