我需要创建一个在IIS中托管的WCF服务,使用HTTP传输并在服务器内存中保持状态。虽然我知道状态服务不是一个好主意,但最后的限制对于使服务与传统客户一起工作是必要的。

我的第一个想法是ASP.NET的会话来存储这些值。我在服务中激活了ASP.NET兼容模式,这使我访问了HTTPContext,但是将其放置在会话对象中的值并未持续在内存中。我认为这是因为处理会话状态的HTTP模块未正确配置,但是当谷歌搜索答案时,我遇到的答案,WCF会话并认为使用它们可能是一个更好的主意。

但是,WCF会议似乎是文档不足的内容,并在服务上放置了一套奇怪的预定,我找不到适合我需求的配置:必须在IIS中托管,必须使用HTTP或HTTPS运输,并且可以't在Windows身份验证上回复,因为客户端和服务器将不属于同一域的一部分。我正在尝试使用WSHTTPBINDING来实现此操作,我听说WCF会话需要安全性或可靠消息,但是: - 使用标准绑定,当服务器不在同一域的一部分时,它会在“ SecurityNegotiation exception”中失败,而呼叫者则会失败。服务没有得到认证”例外。这与使用Windows安全性一样合乎逻辑。

  • 如果我禁用安全性完成,则“合同需要会话,但绑定'wshttpbinding'不支持它或不正确配置以支持它。”

  • 如果在禁用安全性的同时,我启用可靠的消息,我会得到异常“绑定验证失败,因为WSHTTPBINDING不支持有关运输安全性(HTTPS)的可靠会话。无法打开频道工厂或服务主机。使用消息安全,以通过HTTP安全可靠消息传递。”

  • 我尝试启用运输级安全性,但这似乎对生成的错误没有任何影响

是否有可能对我有用的配置?还是我应该回到使用ASP.NET会话的计划?

有帮助吗?

解决方案

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

  1. 创建一个新的WCF服务库项目。该项目将已经包含一项服务 WSHttpBiding 结合预配置。
  2. 转到服务合同(ISERVICE1.CS),然后将ServiceCentract属性更改为以下内容:

    [ServiceContract(SessionMode = SessionMode.Required)]
    
  3. 转到服务强度(Service1.cs),然后将以下服务行为属性添加到服务类(Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
  4. 将会话数据添加为服务类的成员(Service1):

    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
  5. 使用成员介绍特定的会话数据(请记住还将它们添加到服务合同中, 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 确保您的客户进行会话跟踪。
InstanceContextMode.PerSession 确保为每个会话创建服务类(Service1)的实例,以便您可以保留会话数据,并且它将在同一会话中的多个调用中存在内存中。
ConcurrencyMode.Single 确保只有一个线程可以输入每个服务类实例(Service1),并在仅从服务类(以及外部线程安全位置)访问数据时,可以防止可能的问题。

编辑: 默认, WSHttpBinding 仅允许安全会议。但是它还支持可靠的会议,可以在不启用安全性的情况下建立会话。以下绑定配置可禁用安全性并启用可靠的会话:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>

其他提示

IMO这是当您使用像WCF这样的HTTP上抽象不佳的技术时发生的情况。理论上可以托管WCF Web服务没有HTTP(即通过NET TCP,MSMQ等)托管的事实,只是很难在不进入配置地狱的情况下使用HTTP的内置功能,并启动“猜测正确的配置”的游戏通过反复试验“在尝试所有可能的配置排列的地方,直到找到正确的配置置换为止!

最终,如果您无法使用WCF,并且必须从头开始实现Web服务,则只需在客户端成功身份验证时设置cookie即可。然后,使用每个客户端请求,只需获取该cookie引用的会话信息即可。

如果您必须使用WCF,则可能的解决方案是自己手中的会话管理 (这是我对让某些工作所需的努力不满意的事情) 并在所有需要会话/身份验证的Web服务上具有明确的“会话”属性(通常是根据身份验证生成的指南)。因此,对于每个后续请求,您使用GUID来补充与该客户端关联的会话信息。

如果您有兴趣尝试不同的Web服务框架 开源网络服务框架 这使您可以构建不含配置的,干燥,可测试的Web服务,其中(不需要任何配置)您创建的每个Web服务都可以自动访问REST XML,JSON,JSON,JSV,SOAP 1.1,SOAP 1.2端点。有效地,它使您可以通过HTTP获取静止客户端的HTTP获取URL访问同一Web服务,并轻松调试以及SOAP端点(某些企业仍然规定了一种受欢迎的选择)。这 你好世界 教程应该为您提供有关其某些功能及其工作方式的详尽概述。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top