Well, you really touch on two separate issues:
- local vs. remote service availability
- "normal" vs. streamed service (for large files)
In general, if your service works behind a corporate firewall on a LAN, you should use the NetTcpBinding since it's the fastest and most efficient. It's fast and efficient because it uses binary message encoding (vs. text message encoding over the internet).
If you must provide a service for the "outside" world, you should try to use a binding that's as interoperable as possible, and here your choices are basicHttpBinding (totally interoperable - "old" SOAP 1.1 protocols) which cannot be secured too much, and wsHttpBinding which offers a lot more flexibility and options, but is less widely supported.
Since you can easily create a single service with three endpoints, you can really create your service and then define these three endpoints: one for local clients using NetTcpBinding, one of the widest availability using basicHttpBinding, and optionally another one with wsHttpBinding.
That's one side of the story.
The other is: for your "normal" service calls, exchanging a few items of information (up to a few KB in size), you should use the normal default behavior of "buffered transfer" - the message is prepared completely in a buffer and sent as a whole.
However, for handling large files, you're better off using a streaming transfer mode - either "StreamedResponse" if you want clients to be able to download files from your server, or "StreamedRequest" if you want clients to be able to uplaod files, or just plain "Streamed" if you send files both ways.
So besides the three "regular" endpoints, you should have at least another endpoint for each binding that handles streaming exchange of data, i.e. upload/download of files.
This may seems like a lot of different endpoints - but that's really not a problem, your clients can connect to whatever endpoint(s) are appropriate for them - regular vs. streamed and internal/local (netTcpBinding) vs. external (basicHttpBinding) as they need - and in the end, you write the code only once!
Ah , the beauty of WCF! :-)
Marc
UPDATE:
OK, after your comment, this is what I would do:
- create a
ILocalService
service contract with a single method GetFile
that returns a path and file name
- create an implementation for the service contract
- host that service on an endpoint with
netTcpBinding
(since it's internal, local)
[ServiceContract]
interface ILocalService
{
[OperationContract]
string GetFile(......(whatever parameters you need here).....);
}
class LocalService : ILocalService
{
string GetFile(......(whatever parameters you need here).....)
{
// do stuff.....
return fileName;
}
}
and secondly:
- create a second service contract
IRemoteService
with a single method GetFile
which doesn't return a file name as string, but instead returns a stream
- create an implementation for the service contract
- host that service on an endpoint with
basicHttpBinding
for internet use
- make sure to have
transferMode="StreamedResponse"
in your binding configuration, to enable streaming back the file
[ServiceContract]
interface IRemoteService
{
[OperationContract]
Stream GetFile(......(whatever parameters you need here).....);
}
class RemoteService : IRemoteService
{
Stream GetFile(......(whatever parameters you need here).....)
{
// do stuff.....
FileStream stream = new FileStream(....);
return stream;
}
}