I built a DataSnap web service in Delphi-XE2, which uses the TDSServer
and TDSHTTPService
components. Clients attach to the server (web service) and run DataSnap server methods to retrieve data. The server uses TDSLifeCycle.Session
for all connections. I want to continue to use Session
if possible because I store session information in thread variables...
I can use Internet Explorer to authenticate to and retrieve data from the DataSnap server. If I don't let IE sit idle for 30 seconds (or it disconnects from the server), it will reuse the same connection for every method request.
I can use a simple Delphi app that uses TIdHTTP to connect to the DataSnap server. Adding keep-alive
to its Request.Connection
property makes it stay connected forever and reuse the one connection for all method calls.
.
A 3rd party company is building a WCF app to access the DataSnap service. They can't get WCF app to use only one connection to the service. The initial authentication request and 1st method call use the same connection, but subsequent requests create new connections, evident by running netstat
on their computer and seeing new ESTABLISHED connections from their app to my service using multiple source ports. New connections create new threads in the DataSnap server, which can't access the authenticated thread's session variables.
.
I know that I can change the DataSnap server to an Invocation
model, making it unnecessary to maintain one persistent connection per client, and will do this if needed. Before doing so, I thought it prudent to see if anyone else knows how solve the problem.
.
Is it possible for a WCF client app to create a single persistent connection to a non-WCF server (DataSnap server) that it uses for all method calls without it creating new connections? How is this done? Is it as simple as adding the right [decoration] to the C# WCF project in Visual Studio?
Any suggestions are greatly appreciated!
.
FYI - I don't have access to the 3rd party's code, so I can't provide samples of the WCF code.
Your Delphi application provides a stateful web service (using session variables), and WCF web services are stateless by default, including WCF clients.
Maybe this answer points to the correct configuration (wsHttpBinding and SessionMode of the ServiceContract).
From the MSDN ocumentation:
For example, if the SessionMode property is set to SessionMode.Required and the InstanceContextMode property is set to PerSession, clients can use the same connection to make repeated calls to the same service object.
(highlighting by me)
However, as DataSnap is not primarily designed for interoperability with WCF it might be easier to re-design the Delphi side to use a stateless web service model instead of stateful. This would require authentication with every service request, but internally the Delphi web service could some cache data to reduce lookup times, similar to the current session state.