WCF service question - wcf

With traditional ASMX web services synchronous request, the client connects, makes a request and waits for the entire message body to be returned.
I was wondering if its possible to have chunks of data flushed back to the client instead with WCF?
This way I can display some progress to the client app during the operation.

With WCF you can use streaming for download/upload. Check this links:
WCF Streaming in MSDN
File Transfer Progress example in CodeProject

Using WCF you can either use streaming or duplex messages to achieve that. Using streaming you are restricted to returning a single stream object. using duplex duplex messaging you pass a callback channel to the server and it can use that channel to make as many calls as you like to the client.

Related

Returning wcf stream from service fabric actors/services

I am hoping this is a simple question.
I want to create a cluster of services that process dynamic reports that involve any number of several thousand fields. From what I can tell, I can't use a stream as a return type from a reliable actor or service. Are my only options to return serialised byte arrays or to write the results elsewhere and direct clients to query that resource instead, or am I missing something?
Thanks
It depends on the communication stack you use in your services. Services themselves are agnostic to communication protocols. Implementations of services can plug in any communication stack: Web API, WCF, sockets, doesn't matter.
Reliable Actors is a special implementation of a service, and as a service implementation it specifies a communication stack. In that communication stack, request/response payloads have to be DataContract serializable, so no you can't return a stream there.
Otherwise, if you're using WCF to communicate with your services, then you're limited by what WCF can do.
If you're using service remoting (where your service implements IService and you use a ServiceProxy to call methods on it remotely), then no you can't return a stream for a service method. You need to return something that is DataContract serializable.
If you're using Web API in your service, you can grab the HTTP response stream in a controller action method and stream your data back without allocating a byte buffer for it.
Or you can implement your own communicaton protocol and do whatever you want.

when to use duplex service?

Well, I know that in a duplex contract the service can send messages to the client, but I would like to know when that is really useful.
I have a common application that send request to the service to get data from the a database, insert data... etc. Also, I need to store files about 40MB in the database, so I need a good performance. For this reason, I would like to use the net.tcp binding with transfer mode streamed, but the problem is that a net.tcp duplex service can't use the streamed transfer mode.
So I think I have some options.
1.- study if I really need a duplex contract for this kind of application. Perhaps in a chat application, for example, it has more sense a duplex contract because the server perhaps need to notify to the client when a contact is connected... etc. But in a common client that access to a data base, is necessary a duple contract? what kind of operations would can need a duplex contract?
2.- Other option it's not to have a duplex contract, but implement a no duplex contract in the server and other single contract in the the client, so when a client connect to the service, the service receive the needed information to connect to the service of the client. But, is this a good way to avoid a duplex contract?
3.- Really for my application I need tcp instead of a duplex HTTP that allows a streamed transfer mode? What is the advantages of the tcp over the HTTP in terms of performance?
Thanks.
You need duplex if you want to implement callback pattern. Callback means that client does not know when some event happens in server.
If you do not know when event happens you have two options to implement:
Polling - send requests every X minutes to check if event happened. Server should either return event details (if it happened) or return flag saying that you need to continue calling. Server also can return recommended timeout in advanced scenarios.
Callback - client sends some form of description what server should do if event happened. This may be pointer to function in C, delegate in .NET or endpoint schema in WCF. Server remembers that info and makes call from their side when time came.
As you can see duplex/callback means that at some point server works as client (initiates communication) and this is a big game change.
WCF duplex communications may require special network configuration because in many cases network allows you to call external services (you work as client) but forbids external resources to call you (external service works as client). This is implemented for security purposes.
Returning to your questions:
You do not need duplex if you only need to download big amount of data. You may need it if you want to catch updates that happened in server and notify clients. Duplex should work for Chat because in chat there are many scenarios when client needs to be notified with changes introduced by others.
What you described is hand-made variant of duplex channel. You should use proved and tested duplex implementation made by MS If you want server to call your method. Otherwise your option is polling.
You are right, you need tcp + streamed transfer mode to deal with big amount of data. TCP uses binary serialization which is more compact comparing to text serialization + with TCP you do not need to send any HTTP headers or SOAP envelops. Disable security if you do not need it. It has a big performance impact.
Addressing each point:
1, 2. I think that for your scenario a duplex service is an overkill. As you say yourself a duplex service is usually handy when both the client and service need to keep notifying each other on a constant basis, what you're doing, getting lots of data in/out of a database doesn't seem to be a good case for using duplex communication. Regarding netTcpBinding not allowing Streaming with duplex, you can just return a byte array (byte[]) instead of a stream. 40 MB is a lot, but I don't think Streaming will necessarily have a significant performance gain over a duplex service which will return a byte array (up to you to test each setup and compare the results). So you have a few options here, don't stream and return a byte array (you can do this with your duplex service) or you can just forget about making your service duplex since there doesn't seem to be a strong case for you to make it duplex and just return a Stream:
[OperationContract]
Stream RetrieveFile(long _fileId);
[OperationContract]
long SaveFile(Stream _stream);
3. netTcpBinding has a considerable performance advantage over HTTP bindings, but it comes with a price, mostly because its TCP ports are sometimes blocked by internet firewalls, although you can use netTcpBinding over the internet, it's not recommended. Choosing a binding depends on what you're looking to do, if your clients are going to consume your service over the internet, then netTcpBinding is not a good idea (blocked TCP ports, firewalls etc.), but if your clients are consuming the service in the same network (LAN) then netTcpBinding is the most sensible choice. wsDualHttpBinding (doesn't support streaming :#) is a good choice if you want to stick to a duplex service (equivalent of PollingDuplexHttpBinding in Silverlight), or any other HTTP based bindings if you let go of the idea of a duplex service.
Some articles that may help you out, performance comparison of various WCF bindings:
http://blog.shutupandcode.net/?p=1085
http://tomasz.janczuk.org/2010/03/comparison-of-http-polling-duplex-and.html
And about Streaming large data with WCF over HTTP, according to the authors, both samples have been tested with up to 2GB of data:
http://garfoot.com/blog/2008/06/transferring-large-files-using-wcf/
http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP
You shouldn't think that you must use netTcpBinding or you must use Streamed transfer for your service, netTcpBinding only becomes more performant than HTTP bindings after you enable throttling and configure some socket level properties. And streaming 40 MB will not have significant performance gains over buffered transfer. So you have a lot of options and a lot of trade-offs to make. There is no black and white and right or wrong, it's about how you customise your service to suit your needs best, most solutions will work. Your scenrio is a very common one and there are lots of stuff online about large data transfer in WCF, do more research ;)

WCF vs IHttpHandler

Is there something in WCF that can simulate http streaming like IHttpHandler can do?
I want a way to constantly write bytes to my http response non stop to my client until there is nothing left to write using WCF and was just wondering if this is possible?
Thanks
WCF allows streaming by setting the TransferMode property of the binding to 'Streamed', 'StreamedRequest' or 'StreamedResponse', depending on your needs.
Check the following MSDN articles for more information on it:
Streaming Message Transfer
Large Data and Streaming

Bulk calls vs multiple calls in WCF using MSMQ

I am calling a WCF service which contains the business logic to process the message objects.
I need to pass the id of the message to WCF service. We are using MSMQ for queuing up the requests.
There could be multiple messages that WCF service need to process which can be handled as follows
Send the message id one by one
Send array of message ids and then WCF service will iterate through each id and process the message object.
Performance point of view I believe second option is better as multiple requests to WCF are not there.
Is my assumption correct?
-
Ram
Number 2 is more efficient in terms of latency but does not give you the chance to spread the processing load by having multiple queue readers
Also be aware that if you use a transactional queue and sessions then WCF may put more than one SOAP message in each MSMQ message

WCF MSMQ callback function

I have a system that sends a object to another service via WCF using MSMQ. The service picks the message up fine and does what it have to with it. But the problem i have now is that i need to send a response to the calling system.
Example:
Create a Customer object
Populate the information
Send the message to the service using WCF over MSMQ
Pick the message up from the queue using a windows service
Call Customer.Insert() method on the windows service
I now need to send the new customer id back to the calling application here.
Any ideas?
As Emmanuel points out - MSMQ messages are by design one-way and have no response, really.
Your best solution would be to have a response queue where the "other service" can drop his response messages into. Your client would then have to monitor that queue, e.g. check it once in a while (every minute, every 30 minutes - whatever makes sense for you) for new messages, and handle those.
There's no duplex (two-way) MSMQ channels - but you can easily create a pair of separate queues for both directions.
Marc
you can use duplex communication with msmq but not natively, take a look to my article
MSMQ Operation needs to one way, the only way I can think of receiving back a message is for your calling application to also Host a service for responses since there's no duplex MSMQ binding.