I am using netTcpBinding and from what I have read, percall instance context is the recommended way to use wcf. However does this mean that I will not be able to use asynchronous duplex callbacks? Because the service objects are destroyed between method calls so there is no way to perform an async callback on the client? Is this correct?
It seems that if I want to use percall for scalibility, I will be stuck with bad responiveness on client machine because as the callbacks cant be asynchronous. Or have I got it all wrong?
You mix up client instances and server instances. InstanceContextMode.PerCall means that every call from a client gets a new object serving that single request.
The callback channel(s) which you are talking about are communicating the other way round: They call methods in your client. Your client should stay alive and is a single instance from the servers point of view.
So all you need to persist on the server side after a method call is the clients operation context. Because thats the reference you need to send a message to your client by using the callback contract.
So as a result, you can use async callbacks with InstanceContextMode.PerCall, but you will have to provide some session state storage by yourself.
What do you mean exactly with asynchronous duplex callbacks?
You can use a normal duplex contract and then make calls to this in an asynchronous way so that the client doesn't block. Obviously the service object need to stay alive until it has called back to the caller.
Related
I am developing WCF application under Windows Service which is exposing one endpoint. There can be about 40 remote clients who will connect to this endpoint over local area network at the same time. My question is whether WCF can handle multiple calls to the same endpoint by queuing them? No request from any client can be lost. Is there anything special I have to consider when developing application to handle simultaneous calls?
You can choose whether the requests should be handled asynchronously or synchronously one after another.
You can set this behavior via the InstanceContextMode settings. By default WCF handles requests ByCall which means one instance of your service will be created for each incoming request. This allows you to handle multiple requests in parallel.
Alternatively you can configure your service to spin off only one instance which ensures each request is handled after the other. This effectively is the "queuing" you mentioned. You can set this behavior via InstanceContextMode.Single. By chosing this mode, your service becomes a singleton. So this mode ensures there's only one instance of your service, which may come in handy in some cases. The framework handles the queuing.
Additionally you could set ConcurrencyMode.Multiple which allows your single instance to process multiple requests in parallel (see Andrew's comment).
However, be aware that the queued requests aren't persisted in any way. So if your service gets restarted, the not yet finished requests are lost.
I'd definitely recommend to avoid any kind of singleton if possible.
Is there anything that prevents you from chosing the parallel PerCall-mode?
For more details have a look at this: http://www.codeproject.com/Articles/86007/ways-to-do-WCF-instance-management-Per-call-Per
Here are some useful links:
https://msdn.microsoft.com/en-us/library/ms752260(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/hh556230(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute(v=vs.110).aspx
To answer your question, no calls will be lost whatever you choose. But if you need to process them in order, you probably should use this setup for your service
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, EnsureOrderedDispatch = true )]
I'm writing a webservice that drops off a long-running bulk insert command to a sql db through a stored proc. I don't want the webservice hung up while waiting for a response from the db, so I'd like to just return an http response that lets the client know the request has been sent to the db after I start the task. But as soon as I return the response, the task will lose context and get trashed, right? How should I keep this alive?
In general, it's not a good idea to spin off something to do work from IIS. What happens if the AppPool restarts? What happens if there is an exception?
Instead, I would recommend writing a Windows Service and have it responsible for the work.
Based on your comments, I would see if you can ask for the following requirements (theoretically):
All external calls are done through the web service. The web service uses a separate assembly for the actual data access.
A separate windows service is used for long running processes, which would also use the same data access assembly the web service uses.
That is really the best way to go (but not necessarily doable based on requirements).
I think it's more of a architecture question than just about maintaining the 'context'. And talking about architecture, I think WCF webservices would help in your scenario.
What you would need is a service with callback contract. Where the service takes a request, returns an ack, stores the client context (for callback), and triggers off a long running database task in background. When the task completes, it reads client context and calls the callback handler with the result.
This article at MSDN suggests how to do a callback contract in webservice.
Hope this helps!
As stated in the first section of this article (.chm file - see note below)
One-way calls do not equate to asynchronous calls. When one-way calls
reach the service, they may not be dispatched all at once and may be
queued up on the service side to be dispatched one at a time... If the
number of queued messages has exceeded the queue's capacity, then the
client will block, even when issuing a one-way call.
If a one-way call is invoked, when does it return control to the caller? The introduction of the same article states that one-way calls are used for fire-and-forget operations, thereby simulating a kind of asynchronous call.
If a sessionful WCF service has a Login() one-way method which starts the session, when does this method return control to the caller? Does it return before the method is actually executed on the service? If so, how can I be sure that the method was performed on service?
If I wanted the service to return to the client the possible errors that occur during the login procedure, would be an asynchronous call the only way to achieve a fire-and-forget behaviour?
Note: The quote above is taken from an article called WCF Essentials - What You Need To Know About One-Way Calls, Callbacks, And Events by Juval Lowy, and can be found in the October 2006 issue of MSDN magazine. The link above is to a help file (.chm) format on MSDN. If you can't get the linked CHM file to work (I couldn't) you can open it with 7zip.
If a sessionful WCF service has a Login one-way method which starts
the session, when does this method return control to the caller?
For OneWay calls: The caller will continue to execute as soon as the service call is dispatched or queued. Basically as soon as the service successfully receives the call.
how can I be sure that the method was performed on service?
If the client does not get an exception, the service call was (or will be) performed. When the service call actual runs or whether it succeeded or threw an exception is unknown to the client.
If I wanted the service to return to the client the possible errors
that occur during the login procedure, would be an asynchronous call
the only way to achieve a fire-and-forget behaviour?
This does not make sense. Fire-and-forget by definition means forget the result. It does not return any values or errors to the client. However an asynchronous call is not fire-and-forget and would return errors.
I have a WCF service hosted in a Windows Service. I want a website to be able to call it asynchronously and then when the work is finished the WCF service will let the website know the result. I've looked at various ways of achieving this but I would like to get some more advice on which way would be best. I've looked into using callbacks but also read they can be unreliable. I've read about not doing it this way at all and just having another interface in my service for the website to query the status. I've looked at using MSMQ which at the moment looks like my preferred way forward but would like some more info on how to set this up or whether I shouldn't do it this way.
Does anyone have any advice please?
The nature of any communication on a network is unreliable. The statement:
I've looked into using callbacks but also read they can be unreliable
Assuming you mean WCF callbacks, they are as unreliable as the clients/servers themselves, they all use the same mechanism.
That said, you can store the client of your WCF service in the HttpApplicationState (if the call is application-wide) or HttpSessionState (if the call is local to a session).
When generating the proxy, make sure that you check the option (or specify on the contract) that you are using asynchronous calls.
Then, you would make the call, using a callback (delegate) to indicate when the async call completed.
When the call completes, you would then store the result in the session state.
If this is something that a client on the front end needs to be aware of, then the browser will have to poll your site, checking for the return result, redirecting to a page that can display the results when the result is populated.
Selecting a binding for your application depends on
Architecture of your application
Requirements
interoperability required or not.
response time of the application
availability of time to implement
Infrastructure you are using or want to use.
As your application is a web application and is built on a request/response model, you will not be able to use asyncronous or msmq style for this architecture(or is not adviceable), because there will not be any thread listining for a delayed async response or msmq call.
you can make use of one way Methods and direct calls to methods. in this case to reduce response time you have to device ways to optimize your service methods and the processing it is doing.
I have a WCF webservice that acts as a data provider for my ASP.NET web page.
Throughout the web page a number of calls are made to the web service via the auto-generated ServiceClient.
Currently I create a new ServiceClient and open it for each request i.e. Get Users, Get Roles, Get Customer list etc.... Each one of these would create a new ServiceClient and open a new connection.
Can I make my ServiceClient class a global or statically available class so that all functions within my ASP.NET web page can use the same client. This would seem to be far more efficient. Are there any issues with doing it this way? Any advice I should take into account when doing this?
What happens if I make multiple requests to a client? Presumably it is all synchronous so it shouldn't matter if I make 1 or 50 calls to it?
Thanks
When session (wsHttp with security context or reliable session) or connection (net.tcp, net.pipe) oriented binding is used you have to handle your proxy in the way you want to handle the session. So if you share the proxy, all calls will be handled in single WCF session (by default handled by single service instance). But you have to deal with additional complexity like: Unhandled service exception will terminate your channel and following call from client will result in exception.
When session-less HTTP binding (basicHttp, webHttp) is used you can share your proxy or even make it static. Each call is handled separately, exception on a service will not fault the channel and it transparently reuses opened HTTP persistent connections. But because of this, there should be no big overhead to creating new proxy / channel.
So my suggestion is: When you need several calls to your service in single request processing in your ASP.NET application, use the same proxy / channel. But don't share proxy / channel among different requests.
I think using a ChannelFactory could take of your problem. If I'm right the ChannelFactory has a pool of your connection and re-uses the channels. The advantage of this is that the channels don't get instatiated each time, only the first.
Read more here: ChannelFactory
To handle the disposing of the channels you need some special handling since the channel can throw exception in dispose. I wrote a mapper to handle this, you can read about it here: http://blog.tomasjansson.com/2010/12/disposible-wcf-client-wrapper/