For http based wcf service, is there any connection pooling that happens internally? Will the connection be opened and closed for every http request? Through some search, I found something called keep-alive setting but didn't really understand how it works in wcf scenario. Is it possible to implement connection pooling at all for httpbinding service. Below is the use case we have.
The end client system is informatica which consumes wcf service developed by us. Our wcf service in turn calls another external web service (I am not sure if it is a wcf implemented service or on another different platform, not sure if there is a way to dynamically detect this other than asking the vendor).
We would be making thousands of calls to the external service within a span of time and want to optimize it. Send lot of data within a single call is not an option provided by the vendor service yet.
I think opening/closing connection creates lot of overhead. Is there a way to pool the connections for re-using it for http based service?
Thanks,
Shyam
Related
I am using wsHttpBinding to call a WCF web service. When I look into the Fiddler2, I see multiple calls to the server before calling my actual OperationContract.
From this post I understood what these service calls are doing.
However, I want to know if there is any way to avoid these calls after first successful service call.
In my application, the web service is called so frequently that 3-4 additional calls per actual call to web service operation will not be accepted.
As you mentioend what happens is that WCF negotiates for a key. More details in here.
You have a few options:
set negotiateServerCredential and establishSecurityContext to false (this would require the client to have the server certificate out of band)
change to a different security mechanism (user name auth, or transport with SSL)
stay with the current situation. Once the negotiation is established no more extra calls are made. They happen once per proxy generation.
There is no way to make the negotiation process shorter. It consists of several message exchanges since this is the WS-Trust protocol.
What Works
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.
.
Problem
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.
.
Possible Workaround
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.
.
My Question
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.
I'm a WCF newbie, and I need some help to begin with a project:
I will have a managed application (server) that needs to communicate (messaging system) with several clients over the internet and vice versa.
What is the best approach to achieve this?
using wsDualBinding?
UPDATE
I decided to use the NetTcpBinding mode instead.
It depends on what capabilities your service needs to expose, and what type of clients you need to support. Any of the HTTP-based bindings will work over the internet, its simply a question of the way the data is encoded.
A summary of the built-in bindings and what they support can be found here: http://msdn.microsoft.com/en-us/library/ms731092.aspx
But the most common are:
BasicHttpBinding - This is a basic web service-style binding, usable by any SOAP client.
WebHttpBinding - This allows your service to be used by non-SOAP HTTP clients
WsHttpBinding - This allows your service to use extended service features like transactions and sessions.
WsDualHttpBinding - This is required if your service needs a duplex channel, meaning your service needs to make callbacks up to the client.
Since you specifically asked about the dual binding:
If you are writing an application that needs to be able to make a callback from server into the client, then a dual binding is really your only option. Since you specifically mentioned chat, however, I don't think a dual-channel service is going to work very well.
The way the callbacks work in WCF is that your client makes a call to the service, using a dual channel, and must provide an implementation of the callback interface. The server can use this to make calls to the client for the duration of the service method call; the callback context is per-service-call, so once that call returns, it is no longer valid. In other words, your server cannot just asynchronously "call into" your client, it has to wait for the client to "poll" the server. And if you're going to do that, you don't really need the callback anymore.
Honestly, I don't think I would use WCF for an interactive bi-directional chat application, but I can think of two possible options to do so:
Do the polling client option, using a simple BasicHttpBinding on the server and continuously ask for new messages.
Set your client applications up to self-host a local WCF service, and provide the endpoint information to the server when you log in. This requires your clients to accept incoming connections, which gets messy (but if you can pull it off, I'd go for a NetTcpBinding here.)
WSDualHttpBinding is not a good choice for internet. Callback works great only in local network (intranet) that has no Firewall and NAS restrictions.
See this post for more details:
Connecting over internet to WCF service using wsDualHttpBinding times out
Use WsHttpBinding if you want to set up server to server communications (that should work for WPF).
Use WebHttpBinding if you are planning to use data from Javascript.
I have to create a WCF web service that proxies an IMAP service (so that it can be consumed by a SL application).
The IMAP service requires that first the Login(credentials) method is called, to authenticate with the IMAP server. After the Login method is called the connection is kept open and other operations can be performed.
Does anybody know how can achieve this with a WCF service?
One solution I want to avoid is the proxy to login for every operation it has to perform (as the login operation usually takes 1-2 seconds). And I would have to pass the credentials every time: GetMail(credentials), GetFolders(credentials), etc.
I know it is highly recommended that WCF services not to be stateful, but it seems I need to keep the state of IMAP connection for every client. How can I do this?
Thanks!
This is one of those rather rare cases where I think using WCF sessions makes sense:
your first call that calls the IMAP Login method starts a WCF session
any subsequent call will be using the same session
some final call (e.g. something like a Done or Logout) will terminate that session
With a session in WCF, your service class on the server stays in memory for the duration of the entire session, i.e. it's not constantly re-created, and thus you can keep the IMAP connection "live" inside your service class.
Resources:
Sessions, Instancing, and Concurrency (MSDN)
Using Sessions (MSDN)
WCF Sessions - a brief introduction
WCF Sessions
Per-Session Instance Management in WCF
Be aware: WCF sessions are NOT ASP.NET sessions - those are two totally different things! Just to be clear from the get-go.
Also: only a handful of WCF bindings support sessions - netTcpBinding, wsHttpBinding and netNamedPipeBinding (as far as I know)
I have a WCF Service that I want my client to be able to consume from IIS without going through a proxy. The client was consuming asmx service in vbscript using the htc behavior:
<div id="oWSInterop" style="behavior:url(webservice.htc)"></div>
oWSInterop.useService "http://localhost/WSInteroperability.asmx", "WSInteroperability"
Set response = oWSInterop.WSInteroperability.callServiceSync("BuildSingleDoc", 1002, 19499, XMLEncode(sAdditionalDetail))
So basically I just want to make this work with making as few changes as possible on the existing client. Am I forced to use a proxy (that is, a class on the client side that exposes the operations in the WCF service) when consuming a WCF service? I do understand the benefits of a proxy and am not opposed to using it for most other client implementations, but in this case I'm not sure I have the time to deal with it on the client - i just want it to work the way it has been with only the endpoint changing.
A client-side proxy class to call the service?
Yes, you definitely need that (unless you do REST-based WCF services, which you can call with a HttpClient alone) - that's where the whole WCF runtime lives and does its magic.
If you want to call up REST-based services, you can do this without any proxy whatsoever - but then you're left to do XML or JSON parsing yourself. It can be done, but it might not be such a great idea.
What's the problem with the proxy?? It's really just a small wrapper that bundles up your calls into a serialized message and sends it to the server side. No big harm, in my opinion....
What are you seeing? What makes you thank that proxy is an issue? If that is server-side code, it should use the browsers settings (WinINet) which should work fine. Perhaps the "localhost" would be an issue, though, since to the client that still means "talk to yourself" (i.e. not the server).
If that is server side you'll probably need to configure WinHTTP appropriately; in particular, to skip the proxy for local addresses. Of course, "localhost" should loop-back anyway...