WS-Messaging: Sending and Receiving SOAP Messages Using TCP

The ASP.NET Web Service project makes an XML-based Web service to communicate over HTTP. Even developers with no knowledge of XML and HTTP can build a Web Service using the Microsoft.NET framework. This XML-based Web Service project ties up with HTTP protocol. Now, WSE 2.0 (Web Service Enhancements) Messaging API enables you to send and receive SOAP messages using the TCP protocol. This can be accomplished without a HTTP Web server, making it possible to write extremely flexible and lightweight Web services.

WSE provides set of classes to achieve this. These classes support both One-Way Messaging and Request and Response pair models. The One-Way messaging model can be accomplished by the following classes: SoapSender and SoapReceiver. The SoapClient and SoapService classes will support both the One-Way and Request and Response Messaging Models. These classes are part of the WSE 2.0 Microsoft.Web.Services2.Messaging namespace.

Now, you can build a sample application based on the Request and Response model. Here, you use TCP as the transport protocol. Now, create a class that receives a SOAP message as a Request from a SOAP client and Sends a Response Back to the client. To achieve this, you need to create a class that derives from the SoapService Class, as shown here.

Public class SendXMLBasesSMTPMail: SoapService
{
   // Soap Method Implementation goes here.
}

Now, add the SOAP Method called SendSmtpMail to the above SendXMLBasesSMTPMail class. In an ASP.NET Web Service project, you add a [WebMethod] attribute for each method that will exposed to calling over the Internet. Like that here, you will add SoapMethod for each Web method. So, you need to add SoapMethodAttribute to the SendXMLBasesSMTPMail method. In "The Attribute," the word Attribute is optional. So, you also can specify the same attribute as SoapMethod. Every method that is defined in SendXMLBasesSMTPMail should have at least one parameter, either SoapEnvelope or an XML-Serializeable type. Also, it should return either SoapEnvelope or a XML-Serializeable type.

The following code example shows how to create a class that handles the receipt of a SOAP request and returns a response.

Implementing SoapService

public class SendXMLBasesSMTPMail :SoapService
   {
      [SoapMethod("urn:Mail:SendSmtpMail")]
      public SoapEnvelope SendSmtpMail(SoapEnvelope env)
      {
         string fromAddress=env.SelectSingleNode("//fromAddress").
                InnerText;
         string toAddress=env.SelectSingleNode("//toAddress").
                InnerText;
         string subject=env.SelectSingleNode("//subject").InnerText;
         string body =env.SelectSingleNode("//body").InnerText ;

         System.Web.Mail.MailMessage objMsg  = new
                System.Web.Mail.MailMessage();
         objMsg.From =fromAddress ;
         objMsg.To =toAddress ;
         objMsg.Subject =subject ;
         objMsg.Body =body ;

         System.Web.Mail.SmtpMail.Send(objMsg);

         SoapEnvelope tempenv = new SoapEnvelope();
         tempenv.Context.Addressing.Action =
                 env.Context.Addressing.Action ;
         tempenv.CreateBody();
         tempenv.Body.InnerXml =
            String.Format("<x:{0}Response xmlns:x='urn:Mail'>
            <result>Success</result></x:{0}Response>",
            env.Body.SelectSingleNode("*").LocalName);
         return env;


   }
}

Here, a SOAP Message was received as a SoapEnvelope, or it can be passed as a serialized object. The SoapContext for a SoapEnvelope is accessed by using the Context property. When a serializable object is used, it is serialized into or from the <Body> element. Programmatic access to the SoapContext for the SOAP message is not available when a serializable object is used.

WSE 2.0 supports sending and receiving messages using three communications protocols: in-process, TCP, and HTTP. In the case of in-process, the SOAP messages are delivered directly to the receiver without hitting the network layer. You indicate which mechanism you want to use (from either a SoapSender or a SoapReceiver) through a URI, which must conform to the following syntax in WSE 2.0:

protocol_scheme://host [:port_number]/path_info/
  1. Protocol_scheme represents the protocol used for the communication with the Web Service.
  2. Port expresses the port where to send the messages.
  3. Path represents the localization of the resources that make up the Web Services inside a host.

For example, suppose you wanted to register the above SoapService (SendXMLBasesSMTPMail) using TCP protocol and port number as 5018. Then, the URI string will be soap.tcp://babaam:5018/receiver.

WSE 2.0 URI Schemes

Protocol URI Scheme Example
TCP soap.tcp soap.tcp://mymachine:5018/ mysoapReceiver
HTTP http http://mymachine/SreeniService/myservice.wse
No Network Layer soap.inporc soap.inproc://SRamadurai/mysoapReceiver
Public void IntializeMathService()
{
// Forming the the Server URL where our SoapService will be
// Listening to the Client Request.
receiverURL = new Uri(String.Format("soap.tcp://{0}/receiver",
                      System.Net.Dns.GetHostName()));

// initialize and register SOAP receiver objects
SendXMLBasesSMTPMail ServiceIntance = new SendXMLBasesSMTPMail ();
// SoapReceivers class to register a SoapReceiver object with a
// particular URI.

SoapReceivers.Add (receiverURL, ServiceIntance);
}

The above method can be called to initialize or Register the SoapService object. Now, you just finished the Soap Message Receiver part.

WS-Messaging: Sending and Receiving SOAP Messages Using TCP

Now, you can create a Soap client that sends a request to the Soap Receiver. To accomplish that, you need to derive a class from the SoapClient class; it is used to send SOAP request messages to a Web service and to receive SOAP response messages from that Web service using the SendOneWay and/or the SendRequestResponse methods. When SendOneWay is called, a SOAP request is sent to the Web service and the method does not wait for a response; it returns immediately. This also is called calling a Web service asynchronously. In contrast, when SendRequestResponse is called, a SOAP request is sent to the Web service and the method does not return until a response is received. When a SOAP response message is required and you do not want to block the thread, you can use the .NET Framework asynchronous design pattern to send the SOAP message request using the BeginSendRequestResponse method. SOAP messages can be constructed from a SoapEnvelope or a serializable object passed into the SendOneWay or SendRequestResponse method.

The following code example shows how to create a class that creates a Soap Message, sends it as a SOAP request, and returns a response from the SoapService.

Implementing SoapClient:

public class SmtpMailClient:SoapClient
   {
      public SmtpMailClient()
      {

      }
      public SmtpMailClient(Uri uri): base(uri) {}

      [SoapMethod("urn:Mail:SendSmtpMail")]
      public SoapEnvelope SendSmtpMail(SoapEnvelope e)
      {
         return base.SendRequestResponse("SendSmtpMail",e);
      }

   }

The following method will create a SoapRequest Message that we will send to the Soap Receiver.

private void CreateSoapRequest2SendSMTPMail()
{
   SoapEnvelope respEnv;
   SoapEnvelope env = new SoapEnvelope();
   env.Context.Addressing.Action ="urn:Mail:SendSmtpMail";
   env.CreateBody();
   env.Body.InnerXml="<x:SendSmtpMail xmlns:x='urn:Mail'>
      <fromAddress>skbbaba23@gmail.com</fromAddress>
      <toAddress>sragavan@hotmail.com</toAddress>
      <subject>BABA NAM KEVALAM</subject>
      <body>Ananda Marga is the only Mission that will help all
            people.</body></x:SendSmtpMail>";
   try
   {
      SmtpMailClient obj = new SmtpMailClient(receiverUri);
      respEnv=obj.SendSmtpMail(env);
      this.textBox1.Text = respEnv.SelectSingleNode("//result").
                           InnerText;
   }
   catch(Exception ex)
   {
      MessageBox.Show(ex.ToString());
   }
   //MessageBox.Show(respEnv.ToString());

   }
}

HTTP Messaging

So far, I have concentrated on TCP as a transport layer. As mentioned before, WSE 2.0 supports three built-in transports ((HTTP, TCP, and in-proc). However, WSE has an architecture in which it selects the transport to use based on the protocol scheme of the URI that is used to send or receive messages. As long as WSE has a transport that matches the protocol scheme, it will work. Now, I will change the Soap Receiver so that it listens for requests on an HTTP port. It is very straightforward to do this because SoapReceiver implements System.Web.IhttpHandler, and so it can be deployed as an ASP.NET handler. First, you create a virtual directory called WSEHttpMessaging, and put in an Assembly file that is your SoapRecevier. Then, you need to create a web.config that sits in the virtual directory. It configures the handler, and looks like this.

<configuration>
   <system.web>
      <httpHandlers>
         <add verb="*" path=" SendXMLBasesSMTPMail.ashx"
                       type=" EmailClient. SendXMLBasesSMTPMail,
                              SendXMLBasesSMTPMail"/>
      </httpHandlers>
    </system.web>
</configuration>

Now, you need to change the URI it uses to send the Soap Request message to point at the HTTP Port. So, now your SoapReceiver URI is:

http://SRamadurai/WSEHttpMessaging / SendXMLBasesSMTPMail.ashx

Conclusion

To the world, most of the Web services implement Remote Procedure Calls over HTTP. Those Web services are tied up with the HTTP protocol. To make transport-neutral XML, Microsoft Messaging has provided an XML messaging API called the WSE 2.0.Web Services Enhancements toolkit. This API allows messages to be sent and received asynchronously over many protocols. The only difficulty I see with an ASP.NET XML-based Web service here is that a developer should have a little bit of knowledge of XML.



About the Author

SeenivasaRagavan Ramadurai

Seenivasaragavan Ramadurai is a .NET consultant, He has been working with .NET technology since pre beta releases. Seenivasa background includes Master's in Computer Science and B.Sc. Mathematics. He has over 9 years of software development experience with Microsoft technologies and has extensive experience developing client-server, distributed, Web services, and component based applications using Visual Studio .NET. Before moving to .NET, Seenivasa has worked on MFC, COM, ATL, and Visual C++ based applications. If you are looking for a consulting help, contact him at skbbaba23@gmail.com

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Hundreds of millions of users have adopted public cloud storage solutions to satisfy their Private Online File Sharing and Collaboration (OFS) needs. With new headlines on cloud privacy issues appearing almost daily, the need to explore private alternatives has never been stronger. Join ESG Senior Analyst Terri McClure and Connected Data in this on-demand webinar to take a look at the business drivers behind OFS adoption, how organizations can benefit from on-premise deployments, and emerging private OFS …

Most Popular Programming Stories

More for Developers

RSS Feeds