The SOAP Transport is a Transport implementation supporting the SOAP 1.1 and SOAP 1.2 protocols over HTTP or HTTPS. SOAP messages exchanged over the network are formtted according to the Document/Literal (wrapped) message format defined in the WSDL 1.1 specification.
This transport is a good choice if the remote service provided by a Remoting-based C++ application must be accessible by clients written using other frameworks or even other programming languages or runtimes, such as Java or .NET.
The SOAP transport supports interoperability with other SOAP 1.1 or SOAP 1.2 implementations (such as those available for Java or .NET) both directions. Java or .NET clients can consume a web service implemented using Remoting and the SOAP transport. Also, the SOAP transport can be used to invoke web services implemented using other SOAP toolkits. The necessary client code can be generated with the XSDGen and RemoteGenNG tools from an WSDL file.
In addition to basic SOAP 1.1 and SOAP 1.2 support, the following features are also supported by the SOAP transport:
To use the SOAP Transport in a server, the following four steps must be performed:
Furthermore, a @namespace attribute must be added to the service class declaration. Otherwise, a run time error will occur when trying to invoke the web service.
Following is an example code fragment for setting up a SOAP Listener, configuring it to enable MTOM, and registering a service object for use with the listener.
Poco::RemotingNG::SOAP::Listener::Ptr pListener = new Poco::RemotingNG::SOAP::Listener("localhost:8080", ""); pListener->enableMTOM(true); std::string listener = Poco::RemotingNG::ORB::instance().registerListener(pListener); st::string uri = Sample::TimeServiceServerHelper::registerObject( new Sample::TimeService, "TheTimeService", listener );
The SOAP listener will transparently accept SOAP 1.1 and SOAP 1.2 requests and send the response using the appropriate SOAP version.
Please see the Poco::RemotingNG::SOAP::Listener class documentation for detailed information about how to setup and configure the listener.
To use the SOAP Transport in a client, the following two steps must be performed:
Following is an example code fragment for setting up a SOAP Transport, and obtaining a Proxy object for invoking methods on the service object.
Poco::RemotingNG::SOAP::TransportFactory::registerFactory(); Sample::ITimeService::Ptr pTimeService = MyProject::MyClassHelper::find( "http://localhost:8080/soap/TimeService/TheTimeService"); );
If the URI of the remote service does not match Remoting conventions, or, in other words, if it is from a third-party SOAP implementation, a second parameter must be passed to find(), specifying with transport to use. For the SOAP transport, this can be one of the following values:
Example:
Poco::RemotingNG::SOAP::TransportFactory::registerFactory(); Sample::ISampleService::Ptr pService = Sample::SampleServiceClientHelper::find( "http://www.example.com/services/SampleService", "soap-1.2" );
To configure the client transport (e.g., to enable MTOM for client requests, enable HTTP compression, or HTTP authentication), the Transport object must be obtained from the proxy. This is done in two steps. First, the interface pointer obtained from the client helper must be casted to a proxy:
Poco::RemotingNG::Proxy::Ptr pProxy = pTimeService.cast<Poco::RemotingNG::Proxy>();
Second, the Transport object can be obtained from the proxy:
Poco::RemotingNG::SOAP::Transport& trans = static_cast<Poco::RemotingNG::SOAP::Transport&>(pProxy->remoting__transport());
Now that we have access to the Transport object, we can configure it:
trans.enableCompression(true); trans.enableMTOM(true);
Configuration should be done before the first method is invoked over the proxy.
Please see the Poco::RemotingNG::SOAP::Transport class documentation for other configuration options, including timeouts and user-agent string.
The SOAP Transport supports HTTP Basic and Digest authentication. To enable authentication for a proxy object, first obtain the Transport object as shown in the previous section. HTTP Basic Authentication can then be enabled with:
trans.setAuthentication(Poco::RemotingNG::SOAP::Transport::AUTH_BASIC); trans.setUsername("user"); trans.setPassword("s3cr3t");
To enable HTTP Digest Authentication:
trans.setAuthentication(Poco::RemotingNG::SOAP::Transport::AUTH_DIGEST); trans.setUsername("user"); trans.setPassword("s3cr3t"); trans.enableChunkedTransferEncoding(false);
Please note that chunked transfer encoding must be disabled in order to use HTTP Digest Authentication.
It is also possible to enable both Basic and Digest authentication and use whatever the server requests:
trans.setAuthentication(Poco::RemotingNG::SOAP::Transport::AUTH_ANY); trans.setUsername("user"); trans.setPassword("s3cr3t"); trans.enableChunkedTransferEncoding(false);
The performance of the SOAP Transport is considerably lower than the that of the TCP Transport. Some of the reasons for this are:
Applications for which remote method call performance is critical, and which do not need to work with non Remoting applications should therefore prefer the TCP transport to the SOAP transport.
All strings used in remote interfaces must be properly UTF-8 encoded when using the SOAP transport. Encoding errors may lead to failures when parsing SOAP request or response messages.
The following table shows how C++ (and POCO types) are mapped to XML Schema (XSD) types.
C++ Type XSD Type ----------------------------------- bool boolean char byte signed char byte unsigned char unsignedByte short short unsigned short unsignedShort int int unsigned int unsignedInt long int unsigned long unsignedInt float float double double std::string string std::vector<T> sequence std::vector<char> base64Binary std::set<T> sequence std::multiset<T> sequence Poco::Int8 byte Poco::UInt8 unsignedByte Poco::Int16 short Poco::UInt16 unsignedShort Poco::Int32 int Poco::UInt32 unsignedInt Poco::Int64 long Poco::UInt64 unsignedLong Poco::DateTime dateTime Poco::LocalDateTime dateTime Poco::Timestamp dateTime Poco::Timespan long Poco::URI string
The SOAP transport normally uses a plain, unencrypted HTTP connection between the client and the server. To make the SOAP Transport use a secure HTTP socket connection, the following steps must be performed.
On the server side, the listener must be created using a Poco::Net::SecureServerSocket.
Poco::Net::SecureServerSocket serverSocket(8443); std::string listener = Poco::RemotingNG::ORB::instance().registerListener( new Poco::RemotingNG::SOAP::Listener("localhost:8443", "", serverSocket) ); std::string uri = MyProject::MyClassHelper::registerObject( new MyProject::MyClass, "MyObject", listener );
On the client side, the SOAP transport uses a private Poco::Net::HTTPSessionFactory object to create the Poco::Net::HTTPClientSession for talking to the server. So, all that needs to be done to enable HTTPS on the client is to register the Poco::Net::HTTPSSessionInstantiator with the session factory. Then, a https URI can be used to access the web service.
Poco::RemotingNG::SOAP::Transport::httpSessionFactory().registerProtocol( "https", new Poco::Net::HTTPSSessionInstantiator ); Poco::RemotingNG::SOAP::TransportFactory::registerFactory(); MyProject::IMyClass::Ptr pObj = MyProject::MyClassHelper::find( "https://localhost:8443/soap/MyClass/TheObject" );