Why WCF Serialization - wcf

I am struggling to understand answer for one question.
.net standard types are first converted to standard messages. This we call Serialization and will be done by one of the WCF serializer.
Those standard messages are converted to stream of bytes . Its called encoding and done by Encoders and which encoder will do that is decided by binding we choose.
My Question is why this serialization is kept in between, Why.net objects are converted to steams of bytes directly by WCF run-time engine and transferred across.

The only thing that connects a client and a server in WCF is the contract and the serialized XML format to exchange messages between the two parties.
WCF is an interoperable messaging service - it cannot rely on anything for the other party. WCF is NOT a ".NET object remoting" system or anything like that. WCF cannot rely on the other side of the communication being a .NET application, so therefore it cannot just exchange .NET objects.
WCF can talk to and serve data for anything - Ruby, Java - whatever. The smallest common denominator for this are serialized XML messages. Therefore, WCF will serialize your messages into a XML format (text or binary) and send them across the wire.

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.

Should objects exposed via WCF services be DTO only?

I have a WCF application that have a bunch of domain entities (mapped by NHibernate) and service contracts. Currently I'm exposing entities directly via service contracts to WCF clients. But this causes me to encounter many limitations of WCF data contracts specially those related to serialization. For example circular graph limitation, KnownTypes etc.
It seems a better way is to use entities just in server side and using DTOs to transfer objects between WCF server and client. Am I right? Is it a must to be?
WCF is a message-based system - it connects clients and servers basically via XML serialized data messages. Therefore, WCF can only send back and forth static data - it's not a "remote procedure call" or "remote object" system where you'd have functionality transferred from cilent to server and back.
Since anything WCF transfers must be XML serializable, it's really just about data - and so yes - WCF is best suited to just send back and forth DTO style data objects.

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 ;)

Will WCF allow me to use object references across boundaries on objects that implement INotifyPropertyChanged or contain observablecollection objects?

So I've created a series of objects that interact with a piece of hardware over a serial port. There is a thread running monitoring the serial port, and if the state of the hardware changes it updates properties in my objects. I'm using observable collections, and INotifyPropertyChanged.
I've built a UI in WPF and it works great, showing me real time updating when the hardware changes and allows me to send changes to the hardware as well by changing these properties using bindings.
What I'm hoping is that I can run the UI on a different machine than what the hardware is hooked up to without a lot of wiring up of events. Possibly even allow multiple UI's to connect to the same service and interact with this hardware.
So far I understand I'm going to need to create a WCF service. I'm trying to figure out if I'll be able to pass a reference to an object created at the service to the client leaving events intact. So that the UI will really just be bound to a remote object.
Am I moving the right direction with WCF?
Also I see tons of examples for WCF in C#, are there any good practical use examples in VB that might be along the lines of what I'm trying to do?
No, WCF is a message based system - you pass around serialized (text/xml) messages. There's no "object references" that you can pass around.
The client has a proxy, which gives you the ability to "call" the service method. The WCF runtime then captures the parameters to that call, packages them up in a serialized message, and sends that message across the wire.
There is no direct connection between the client and the server - the client can't "reach over" to the service to get a remote object, nor can the service go back to the client to find out who called it or anything like that.
All that you want to send to the service must be part of either the message itself, or the headers that accompany the message.
Those messages must conform to the XML schema standard, which again means: only concrete non-generic types. You can't pass around interfaces, you cannot pass references - only concrete types made up of basic types such a string, int, datetime etc.
Update: maybe you need to check out the publish/subscribe (pub/sub for short) pattern - which you can also build using WCF. This would allow you data collection machine to publish its data on a regular basis or whenver it changes, and any number of subscribers could be notified of those changes.
Check out some of those articles - googling or binging for "WCF pub sub" will definitely turn out quite a few more!
Tom Hollander: Building a Pub/Sub Message Bus with WCF and MSMQ
Pub/sub sample with WCF net.tcp protocol in Silverlight 4
Pub/sub sample using HTTP polling duplex WCF channel in Microsoft Silverlight 3
WCF Router and Publish/Subscribe Sample Implementation

Need some help/advice on WCF Per-Call Service and NServiceBus interop

I have WCF Per-Call service which provides data for clients and at the same time is integrated with NServiceBus.
All stateful objects are stored in UnityContainer which is integrated into custom service host.
NServiceBus is configured in service host and uses same container as service instances.
Every client has its own instance context(described by Juval Lowy in his book in chapter about Durable Services).
If I need to send request over bus I just use some kind of dispatcher and wait response using Thread.Sleep().Since services are per-call this is ok afaik.
But I am confused a bit about messages from bus, that service must handle and provide them to clients. For some data like stock quotes I just update some kind of stateful object and and then, when clients invoke GetQuotesData() just provide data from this object.
But there are numerous service messages like new quote added and etc.
At this moment I have an idea to implement something like "Postman daemon" =)) and store this type of messages in instance context. Then client will invoke "GetMail()", receive those messages and parse them. Problem is that NServiceBus messages are "Interface based" and I cant pass them over WCF, so I need to convert them to types derived from some abstract class.
I Don't know what is best way to handle this situation.
Have you considered a "pure" NServiceBus solution for communicating back to clients? NServiceBus already has that "Postman daemon" capability. NServiceBus messages don't have to be interfaces - you can use regular classes as well.
Hope that helps.