The Binary Transport is a very efficient Transport implementation, based on TCP (or SSL/TLS) sockets and a compact, binary message serialization format based on Poco::BinaryWriter. This makes the Binary Transport well suited for distributed applications built entirely in C++, using Remoting.
To use the Binary Transport in a server, the following three steps must be performed:
Following is an example code fragment for setting up a Binary Transport listener, and registering a service object for use with the listener.
Poco::Remoting::Binary::TransportFactory::registerFactory();
Poco::Remoting::ORB::instance().registerListener(
new PocoRemoting::Binary::Listener(10001)
);
std::string uri = MyProject::MyClassHelper::registerObject(
new MyProject::MyClass,
"MyObject",
10001,
Poco::Remoting::Binary::Transport::ID
);
To use the Binary Transport in a client, the following two steps must be performed:
Following is an example code fragment for setting up a Binary Transport, and registering a service object for use with the transport.
Poco::Remoting::Binary::TransportFactory::registerFactory();
MyProject::IMyClass::Ptr ptrObj = MyProject::MyClassHelper::findObject(
hostName,
"MyObject",
10001,
Poco::Remoting::Binary::Transport::ID
);
On the server side, the Binary Transport Listener uses a Poco::Net::TCPServer for handling incoming requests. Each client proxy object maintains its own socket connection to the server, and the socket connection is kept open for the entire lifetime of the proxy. This means that the server has to maintain a separate thread for every client proxy connected to it. Clients therefore should not keep unused proxy objects alive. Creating a proxy object is a fast operation. So, in order to reduce server load, it can make sense for a client to create a proxy object for a rapid sequence of remote method calls, or even a single remote method call, if more than a few seconds pass between (sequences of) calls.
The performance of the Binary Transport is best when no namespaces are used and all remote method parameters are scalar. While the Binary Transport will ignore namespaces and element/attribute distinction, it will still be informed of them by de-/serializers which costs time. Also, the generated code will be more compact when namespaces are not used.
The Remoting Transport supports two special transport features, late connect and automatic reconnect.
If the Poco::Remoting::Binary::Transport object is created with the first constructor argument (lateConnect) set to true, the socket connection to the server will not be established until the first remote method call is performed. This can be helpful in a scenario where client and server processes start up simultaneously, and the client creates (but not yet calls remote methods through) its proxy objects before the server is ready.
If the Poco::Remoting::Binary::Transport object is created with the second constructor argument (reconnect) set to true, the transport will automatically try to re-establish a connection to the server if the connection gets terminated due to a network or server failure, or any other network error occurs during a request. Note that the request during which the failure occurs will not be resent automatically. However, for the next request sent over the same transport, a new connection will be established.
The Binary Transport normally uses a plain TCP socket connection between the client and the server. To make the Binary Transport use a secure SSL/TLS 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(10011);
Poco::Remoting::ORB::instance().registerListener(
new PocoRemoting::Binary::Listener(serverSocket)
);
std::string uri = MyProject::MyClassHelper::registerObject(
new MyProject::MyClass,
"MyObject",
10001,
Poco::Remoting::Binary::Transport::ID,
true
);
Note the last argument to the registerObject() function, having a value of true. This tells the ORB to generate an URI that contains a scheme that indicates that a secure connection is used.
On the client side, the transport must be created with a user-supplied socket factory (Poco::Remoting::Binary::Transport::SocketFactory) that, depending on the actual protocol used, creates either a Poco::Net::StreamSocket, or a Poco::Net::SecureStreamSocket. Such an implementation is shown below:
class SSLSocketFactory: public Poco::Remoting::Binary::Transport::SocketFactory
{
public:
Poco::Net::StreamSocket createSocket(const Poco::URI& uri)
{
Poco::Net::SocketAddress addr(uri.getHost(), uri.getPort());
if (uri.getScheme() == "remotings")
return Poco::Net::SecureStreamSocket(addr);
else
return Poco::Net::StreamSocket(addr);
}
};
The Transport Factory can now be registered with the custom Socket Factory:
Poco::Remoting::Binary::Transport::SocketFactory::Ptr pSocketFactory = new SSLSocketFactory;
Poco::Remoting::Binary::TransportFactory::registerFactory(false, false, pSocketFactory);
MyProject::IMyClass::Ptr ptrObj = MyProject::MyClassHelper::findObject(
hostName,
"MyObject",
10001,
Poco::Remoting::Binary::Transport::ID,
true
);
Note the last argument to the registerObject() function, having a value of true. This tells the ORB that a secure connection is used.