2009-10-13 3 views
0

Je crée un service WCF qui peut être utilisé localement ou à distance et traite des fichiers utilisant parfois des applications de composants tiers qui nécessitent malheureusement un chemin d'accès au fichier réel sur le système de fichiers, pas un flux .net ou quelque chose comme cette. Y a-t-il une approche standard pour cette situation, en termes de ce que les paramètres pour les opérations de contrat devraient être etc.? Bien que je suppose que cela ne peut pas être vital car il doit finalement fonctionner de manière acceptable dans les cas locaux et distants, je préférerais que, dans le cas local, il n'a pas à lire le fichier entier du système de fichiers, inclure le contenu du message, et le rematérialiser à nouveau sur le système de fichiers, mais pour une utilisation à distance, cela est nécessaire. Y a-t-il un moyen de le faire, par exemple en ayant un type FSRefDoc qui sérialise différemment selon qu'il est utilisé localement ou à distance?Meilleure pratique pour les services WCF utilisés à la fois localement et à distance qui traitent des fichiers volumineux sur le système de fichiers?

edit: Pour clarifier: Le problème est que je veux envoyer différents éléments d'information entièrement dans les deux cas. Si je contrôle un service local, je peux simplement envoyer un chemin au fichier sur le système de fichiers local, mais s'il s'agit d'un service distant, je dois envoyer le contenu du fichier lui-même. Bien sûr, je peux envoyer le contenu dans les deux cas, mais cela signifie que je perds la performance dans le cas local. Peut-être que je ne devrais pas m'inquiéter pour ça.

+0

Il semble que vous ayez un service WCF qui vous oblige à écrire sur un système de fichiers local. Vous pouvez toujours utiliser le streaming ou le partage pour envoyer les données du fichier au service. Je ne suis pas ce que vous parlez de cette différence entre local et distant? – RichardOD

Répondre

0

Eh bien, vous touchez vraiment sur deux questions distinctes: le service

  • disponibilité locale vs service à distance
  • "normal" par rapport cams (pour les gros fichiers)

En général, Si votre service fonctionne derrière un pare-feu d'entreprise sur un réseau local, vous devriez utiliser NetTcpBinding car c'est le plus rapide et le plus efficace. C'est rapide et efficace car il utilise l'encodage des messages binaires (vs l'encodage des messages texte sur Internet). Si vous devez fournir un service pour le monde "extérieur", vous devriez essayer d'utiliser une liaison aussi interopérable que possible, et ici vos choix sont basicHttpBinding (totalement interopérable - "vieux" protocoles SOAP 1.1) qui ne peuvent pas être trop sécurisé, et wsHttpBinding qui offre beaucoup plus de flexibilité et d'options, mais est moins largement pris en charge. Comme vous pouvez facilement créer un seul service avec trois points de terminaison, vous pouvez vraiment créer votre service, puis définir ces trois points de terminaison: un pour les clients locaux utilisant NetTcpBinding, l'un des plus larges avec basicHttpBinding et un autre avec wsHttpBinding .

C'est un aspect de l'histoire. L'autre est: pour vos appels de service "normaux", en échangeant quelques informations (jusqu'à quelques Ko), vous devriez utiliser le comportement normal par défaut de "transfert en mémoire tampon" - le message est préparé complètement dans un tampon et envoyé dans son ensemble. Cependant, pour gérer des fichiers volumineux, il est préférable d'utiliser un mode de transfert en continu - soit "StreamedResponse" si vous voulez que les clients puissent télécharger des fichiers depuis votre serveur, soit "StreamedRequest" si vous voulez que les clients soient capable d'uplaod des fichiers, ou tout simplement "Streamed" si vous envoyez des fichiers dans les deux sens. Donc, en plus des trois points d'extrémité "réguliers", vous devez avoir au moins un autre point d'extrémité pour chaque liaison qui gère l'échange de données en continu, c'est-à-dire le téléchargement/téléchargement de fichiers. Cela peut sembler être un grand nombre de points de terminaison différents - mais ce n'est vraiment pas un problème, vos clients peuvent se connecter à n'importe quel point de terminaison (s) approprié pour eux - régulier vs c.-à-d.streamed et interne/local (netTcpBinding) vs externe (basicHttpBinding) comme ils en ont besoin - et à la fin, vous écrivez le code une seule fois!

Ah, la beauté de la WCF! :-)

Marc

MISE À JOUR:
OK, après votre commentaire, voici ce que je ferais:

  • créer un contrat de service avec ILocalService une seule méthode qui retourne une GetFile chemin et nom de fichier
  • créer une implémentation pour le contrat de service
  • hôte ce service sur un point final avec netTcpBinding (car il est interne, locale)

[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; 
    } 
} 

et d'autre part:

  • créer un second contrat de service IRemoteService avec une seule méthode GetFile qui ne renvoie pas de nom de fichier en tant que chaîne, mais retourne un flux
  • créer une implémentation pour le contrat de service
  • hôte de ce service sur un terminal avec basicHttpBinding pour internet
  • assurez-vous d'avoir transferMode="StreamedResponse" dans votre configuration de liaison, pour permettre le streaming le fichier sur

[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; 
    } 
} 
+0

Merci beaucoup pour votre réponse. Mais j'ai peur que cela indique que ma question n'était pas assez claire, alors laissez-moi essayer encore: Le problème est que je veux envoyer différentes informations dans les deux cas. Si je contrôle un service local, je peux simplement envoyer un chemin au fichier sur le système de fichiers local, mais s'il s'agit d'un service distant, je dois envoyer le contenu du fichier lui-même. Bien sûr, je peux envoyer le contenu dans les deux cas, mais cela signifie que je perds la performance dans le cas local. Peut-être que je ne devrais pas m'inquiéter pour ça. –

+0

Merci. C'est plus ou moins ce que j'ai décidé de faire. –

1

OK,

Après votre mise à jour, je considérerais ce qui suit.

1) Créez une méthode qui prend un chemin. Exposez cela via une liaison de canal nommé et utilisez-le localement. 2) Créez une méthode qui prend un fichier (tableau de flux/octets, etc.). Exposez cela en utilisant une liaison appropriée (sur un point de terminaison différent) pour les ordinateurs non locaux (dans un scénario de réseau local, TCP est généralement votre meilleur pari).

Ensuite, tout ce que vous devez faire est de vous assurer que vous ne dupliquez pas la même logique métier. Donc, en un mot, créez 2 interfaces de service différentes, 2 points de terminaison différents et 2 liaisons différentes.

Questions connexes