我需要创建一个在IIS中托管的WCF服务,该服务使用http传输并在服务器内存中保持状态。虽然我知道有状态服务不是一个好主意,但要使服务与旧版客户端一起使用,必须要有最后一个约束。

我的第一个想法是在asp.net的 session 中存储值。我在服务中激活了asp.net兼容模式,这使我可以访问HttpContext,但是 session 对象中放置的值不会保留在内存中。我认为这是因为未正确配置用于处理 session 状态的http模块,但是在谷歌搜索答案时遇到了WCF session ,并认为使用它们可能是一个更好的主意。

但是,WCF session 似乎是文档不足的部分,并且对服务提出了一系列奇怪的先决条件,而我一直无法找到适合我需要的配置:必须托管在IIS中,必须使用http或https传输,并且请不要对Windows身份验证进行回复,因为客户端和服务器不会属于同一域。我正在尝试使用wsHttpBinding进行此操作,我听说WCF session 需要安全性或可靠的消息,但是:
-使用标准绑定(bind),并且当服务器不在同一个域中时,它将失败,并显示“SecurityNegotiationException调用方未通过服务进行身份验证”异常。这与使用Windows安全性相当合乎逻辑。

  • 如果禁用安全性,则完全失败,并显示“契约(Contract)需要 session ,但是绑定(bind)'WSHttpBinding'不支持或未正确配置为支持它。”
  • 如果在禁用安全性的同时启用了可靠消息,则会收到“绑定(bind)验证失败,因为WSHttpBinding不支持基于传输安全性(HTTPS)的可靠 session 的异常。 channel 工厂或服务主机无法打开。使用消息安全性来通过HTTP进行安全可靠的消息传递。”
  • 我尝试启用传输级别的安全性,但这似乎对生成的
  • 错误没有任何影响

    有什么配置对我有用吗?还是我应该回到使用asp.net session 的计划?

    最佳答案

    您可以让WCF以非常简单的方式将 session 信息保存在内存中。为了消除我的说明中的任何可能的外部影响,我假设您从一个全新的项目开始:

  • 创建一个新的WCF服务库项目。该项目将已经包含预先配置了WSHttpBiding绑定(bind)的服务。
  • 转到服务契约(Contract)(IService1.cs),并将ServiceContract属性更改为以下内容:
    [ServiceContract(SessionMode = SessionMode.Required)]
    
  • 转到服务实现(Service1.cs)并将以下ServiceBehavior属性添加到服务类(Service1):
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
  • 将 session 数据添加为服务类的成员(Service1):
    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
  • 使用成员来呈现特定于 session 的数据(请记住也将它们添加到服务契约(Contract)IService1中):
    public class Service1 : IService1
    {
        ...
    
        public string Welcome(string fullName)
        {
            UserFullName = fullName ?? "Guest";
            return string.Format("Welcome back, {0}!", UserFullName);
        }
    
        public string Goodbye()
        {
            return string.Format("Come back soon, {0}!", UserFullName ?? "Guest");
        }
    
        ...
    }
    

  • SessionMode.Required 确保对您的客户进行 session 跟踪。
    InstanceContextMode.PerSession 确保为每个 session 创建服务类(Service1)的实例,以便您可以在其中保留 session 数据,并且该数据将存在于同一 session 中多个调用的内存中。
    ConcurrencyMode.Single 确保只有一个线程可以进入每个服务类实例(Service1),并且如果您仅从服务类(和外部线程安全的位置)访问数据,则可以防止可能的并发问题。

    编辑:默认情况下,WSHttpBinding仅允许安全 session 。但是它也支持可靠的 session ,这允许在不启用安全性的情况下建立 session 。以下绑定(bind)配置禁用安全性并启用可靠的 session :
    <wsHttpBinding>
        <binding name="wsHttpBindingConfiguration">
            <security mode="None" />
            <reliableSession enabled="true" />
        </binding>
    </wsHttpBinding>
    

    09-25 18:28
    查看更多