2009-09-04 4 views
0

J'ai créé le service WCF (hôte sur le service Windows) sur le serveur de la balance de charge. Chaque instance de service conserve la liste des utilisateurs actuels. Par exemple. L'instance A a l'utilisateur A001, A002, A005, l'instance B a l'utilisateur A003, A004, A008 et ainsi de suite.Meilleure façon de partager des données entre une instance d'application .NET?

Sur chaque service dispose d'une interface qui permet d'obtenir la liste des utilisateurs, je m'attends à ce que cette méthode renvoie tous les utilisateurs dans toutes les instances de service. Par exemple. obtenir la liste des utilisateurs de l'instance A ou l'instance B retournera A001, A002, A003, A004, A005 et A008.

Actuellement, je pense que je vais stocker la liste des utilisateurs actuels sur la base de données, mais cette liste semble mettre à jour si souvent.

Je veux savoir, est-ce qu'il a un autre moyen de partager des données entre les services WCF qui conviennent à ma situation?

+0

Essayez cette réponse: http://stackoverflow.com/questions/617256/best-way-to-share-session-state-tate-data-between-two-net-applications –

Répondre

1

Une base de données semble offrir un stockage persistant qui peut être utile ou important pour votre application. En outre, il prend en charge les transactions, etc., qui peuvent vous être utiles. Beaucoup de mises à jour peuvent être un problème de performances, mais cela dépend des nombres exacts, des modèles de requête, du moteur de base de données utilisé, de la localité, etc.

Une alternative à cette option peut être une sorte de serveur de mise en cache en mémoire, comme memcached. Bien que cela puisse être partagé et accédé d'une manière similaire à un serveur de base de données, il existe certaines mises en garde. Premièrement, ces plates-formes ne sont généralement pas soutenues par une sorte de stockage permanent. Que se passe-t-il lorsque le serveur memcached meurt? Deuxièmement, ils peuvent ne pas être assez conformes à l'ACID pour votre usage. Que se passe-t-il sous la charge en termes d'ajouts et de mises à jour?

0

L'option DB est bonne. S'il n'y a pas de problèmes de performance, c'est un design simple qui devrait fonctionner. Si vous pouvez vous permettre d'être semi-temps réel et non-persistant, l'one-way serait de maintenir la liste en mémoire dans chaque service et ensuite chaque service met à jour l'autre quand un nouvel utilisateur se joint. Cela peut être fait comme une sorte de diffusion via un service centralisé ou en utilisant msmq, etc.

2

Personnellement, l'option de base de données me parait trop complexe simplement basée sur la notion de stockage des utilisateurs actuels. Si vous stockez plus que cela, l'utilisation d'une base de données peut sembler logique. Mais en supposant que vous vouliez simplement une liste des utilisateurs actuels des deux instances de votre service WCF, j'utiliserais une solution en mémoire, quelque chose comme un dictionnaire générique statique. Tant que les services peuvent être identifiés de manière unique, j'utiliserais l'ID de service unique comme clé dans le dictionnaire et je couplerais chaque clé avec une liste générique de noms d'utilisateur (ou une structure de données utilisateur appropriée) pour ce service. Quelque chose comme:

private static Dictionary<Guid, List<string>> _currentUsers; 

Étant donné que ce dictionnaire serait partagé entre deux services WCF, vous devrez synchroniser l'accès à celui-ci. Voici un exemple.

public class MyWCFService : IMyWCFService 
{ 
    private static Dictionary<Guid, List<string>> _currentUsers = 
     new Dictionary<Guid, List<string>>(); 

    private void AddUser(Guid serviceID, string userName) 
    { 
     // Synchronize access to the collection via the SyncRoot property. 
     lock (((ICollection)_currentUsers).SyncRoot) 
     { 
      // Check if the service's ID has already been added. 
      if (!_currentUsers.ContainsKey(serviceID)) 
      { 
       _currentUsers[serviceID] = new List<string>(); 
      } 
      // Make sure to only store the user name once for each service. 
      if (!_currentUsers[serviceID].Contains(userName)) 
      { 
       _currentUsers[serviceID].Add(userName); 
      } 
     } 
    } 

    private void RemoveUser(Guid serviceID, string userName) 
    { 
     // Synchronize access to the collection via the SyncRoot property. 
     lock (((ICollection)_currentUsers).SyncRoot) 
     { 
      // Check if the service's ID has already been added. 
      if (_currentUsers.ContainsKey(serviceID)) 
      { 
       // See if the user name exists. 
       if (_currentUsers[serviceID].Contains(userName)) 
       { 
        _currentUsers[serviceID].Remove(userName); 
       } 
      } 
     } 
    } 
} 

Étant donné que vous ne il serait probablement pas envie utilisateurs répertoriés deux fois pour un service spécifique, le sens de remplacer le List<string> avec HashSet<string>.

+0

Comment synchroniser ces données entre les services ? – Anonymous

0

Si vous reconsidérer et héberger en utilisant IIS, vous constaterez qu'avec une seule ligne dans un fichier de configuration, vous pouvez rendre les objets ASP Global, Application et Session disponibles. Cette astuce est également très pratique car cela signifie que vous pouvez partager l'état de la session entre une application ASP et un service WCF.

1

J'aime la mémoire. En fait, je suis en train de concevoir un même mécanisme pour l'un de mes projets que je travaille actuellement. C'est bon pour les scénarios où vous n'avez pas la possibilité d'accéder à la base de données ou certaines personnes hésitent vraiment à créer une table pour stocker des informations simples comme une liste d'utilisateurs par rapport à un nom de machine.

Seule mise à jour que je ferais il y a un noeud ne retournera la liste de ses utilisateurs disponibles à son homologue et pair va combiner cela avec sa liste existante. Renvoyez ensuite sa liste existante au pair qui a appelé. Voilà comment tous les pairs seraient synchronisés avec la même liste.

Questions connexes