2009-09-04 79 views
0

我在负载均衡服务器上创建了WCF服务(Windows服务上的主机)。每个此服务实例维护当前用户的列表。例如。实例A具有用户A001,A002,A005,实例B具有用户A003,A004,A008等。在.NET应用程序实例之间共享数据的最佳方式?

在每个服务都有用来获取用户列表的接口,我期望这个方法返回所有服务实例中的所有用户。例如。从实例A获得用户列表或者实例B将返回A001,A002,A003,A004,A005和A008。

目前我认为我会将当前用户的列表存储在数据库上,但这个列表似乎经常更新。

我想知道,它有另一种方式来共享适合我的情况的WCF服务之间的数据?

+0

试试这个答案:http://stackoverflow.com/questions/617256/best-way-to-share-session-state-type-data-between-two-net-applications – 2009-09-04 02:16:08

回答

1

数据库似乎提供了一个永久性存储,对您的应用程序可能有用或重要。另外它支持对你有用的交易等。很多更新可能是一个性能问题,但它取决于确切的数字,查询模式是什么,使用的数据库引擎,本地化等。

此选项的替代可能是某种内存缓存服务器memcached的。虽然这可以与数据库服务器以类似(某种)方式共享和访问,但有一些注意事项。首先,这些平台通常不受某种永久存储的支持。当memcached服务器死亡时会发生什么?其次,它们可能不符合ACID标准供您使用。在加载和更新方面会发生什么?

0

DB选项听起来不错。如果没有性能问题,这是一个简单的设计应该工作。如果你能负担得起半实时的,并且非永久性的一种方法是维护每个服务的内存中的列表,然后每个服务在新用户加入时更新另一个服务。这可以通过中央服务或使用msmq等进行某种广播。

2

就个人而言,数据库选项听起来像是矫枉过正,只是基于存储当前用户的概念。如果你实际存储的不止这些,那么使用数据库可能是有道理的。但是,假设您只是想从WCF服务的两个实例中获取当前用户的列表,我会使用内存中的解决方案,就像是一个静态的通用字典。只要服务可以唯一标识,我就会使用唯一的服务ID作为字典中的关键字,并将每个关键字与该服务的用户名称(或某些适当的用户数据结构)的通用列表配对。例如:

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

由于此字典将在两个WCF服务之间共享,因此您需要同步对它的访问。这是一个例子。

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

既然你不想特定服务列出两次的用户,它很可能是有意义与HashSet<string>更换List<string>

+0

如何在服务之间同步这些数据? – Anonymous 2009-09-04 06:05:49

0

如果您重新考虑并使用IIS主机,您会发现在配置文件中使用单行可以使ASP Global,Application和Session对象可用。这个技巧也非常方便,因为这意味着你可以在ASP应用程序和WCF服务之间共享会话状态。

1

我喜欢记忆的方式。其实我正在为我现在工作的项目设计一个相同的机制。这对于没有机会访问数据库的场景很有用,或者有些人真的不愿意创建一个表来存储简单信息,如用户列表中的机器名称。

只有更新我会在那里做一个节点将只返回其可用用户列表到其对端,同行将结合它的现有列表。然后将其现有列表返回给调用的同伴。这就是所有的同龄人如何与同一个名单同步。

相关问题