我需要创建一个在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安全性相当合乎逻辑。
有什么配置对我有用吗?还是我应该回到使用asp.net session 的计划?
最佳答案
您可以让WCF以非常简单的方式将 session 信息保存在内存中。为了消除我的说明中的任何可能的外部影响,我假设您从一个全新的项目开始:
WSHttpBiding
绑定(bind)的服务。 [ServiceContract(SessionMode = SessionMode.Required)]
Service1
):[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
Service1
):public class Service1 : IService1
{
...
private string UserFullName { get; set; }
...
}
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>