1

在 WCF 中管理状态的最可扩展的方法是什么。

我只需要一个变量来指示会话,我将在 MSSQL 中管理与会话相关的信息。我不需要知道会话何时结束。每天一次,我将清除所有旧会话。

看来 SessionID 就是那个变量。

对于规模,我使用 Per Call,因为 ctor 是空的。我认为我不需要每次会话。

在我简单的 EightBall 测试中,我得到了一个代表会话的 SessionID。但我只是在一个盒子上测试。

让我担心的是,我看到一些文档需要将 ReliableSessionBindingElement 设置为 On 并且默认情况下它是 Off 。

在以下配置中,SessionID 是否会成为会话的可靠指标?

<system.serviceModel>
    <services>
      <service name="MajicEightBallServiceLib.MagicEightBallService"
               behaviorConfiguration="EightBallServiceMEXBehavior" >
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="MajicEightBallServiceLib.IEightBall" />
        <endpoint address="mex"
                  binding ="mexHttpBinding"
                  contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/MagicEightBallService"/>
          </baseAddresses>
        </host>             
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="EightBallServiceMEXBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerCall)]
public class MagicEightBallService : IEightBall
{
    public MagicEightBallService()
    {
        Console.WriteLine("Eightball awaits your question ...");
    }
    public string ObtainAnswerToQuestion(string userQuestion)
    {
        return "maybe " + OperationContext.Current.SessionId.ToString();
    }

    public sDoc GetSdoc(int sID)
    {
        List<sDocProp> props = new List<sDocProp>();
        sDocProp prop1 = new sDocProp { ID = 1, Name = "Prop1", ArrivalStatus = ArrivalStatus.OnTime };
        props.Add(prop1);
        sDocPropStringSV prop2 = new sDocPropStringSV { ID = 1, Name = "Prop1", ArrivalStatus = ArrivalStatus.OnTime, Value = "StrValue1" };
        props.Add(prop2);
        sDoc sDoc = new sDoc { sID = sID, sParID = 1, Props = props, SessionID = OperationContext.Current.SessionId.ToString() };
        return sDoc;
    }
4

1 回答 1

2

WCF 支持 4 种类型的会话,可靠会话只是其中一种。所以你不需要打开 set ReliableSessionBindingElement On 来启用会话。您可以使用其他会话类型。

实现了 WS-ReliableMessaging 规范的System.ServiceModel.Channels.ReliableSessionBindingElementWS-ReliableMessaging 规范提供了对可靠会话的支持,在这些会话中,消息按顺序且只传递一次,即使消息在会话期间跨多个节点传输,也能保证信心。

实际上wsHttpBinding,默认情况下使用安全会话来加密和数字签名消息。

在以下配置中,SessionID 是否会成为会话的可靠指标?

服务可以检查您的绑定是否配置为使用会话使用ServiceContractAttribute.SessionMode属性。

以下服务合同要求配置的绑定使用会话。

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IEightBall

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.sessionmode.aspx

在 WCF 中管理状态的最可扩展的方法是什么。

InstanceContextMode.PerCall如果您的代码不依赖于除 Session ID 之外的任何会话数据,那么它是正确的选择。会话 ID 是 WCF 消息的一部分,因此无需保留InstanceContext超过处理请求所需的时间。

另一个问题:

在以下配置中,SessionID 是否会成为会话的可靠指标?

答案是肯定的。下面是逆向工程的 property 代码System.ServiceModel.OperationContext.SessionId。正如你所看到SessionId的,只有在不为空时才返回Channel.Session非空值。SessionIdSession

public string SessionId
{
    get
    {
        if (this.channel != null)
        {
            IChannel innerChannel = this.channel.InnerChannel;
            if (innerChannel != null)
            {
                ISessionChannel<IDuplexSession> sessionChannel = innerChannel as ISessionChannel<IDuplexSession>;
                if (sessionChannel != null && sessionChannel.Session != null)
                {
                    return sessionChannel.Session.Id;
                }
                ISessionChannel<IInputSession> sessionChannel2 = innerChannel as ISessionChannel<IInputSession>;
                if (sessionChannel2 != null && sessionChannel2.Session != null)
                {
                    return sessionChannel2.Session.Id;
                }
                ISessionChannel<IOutputSession> sessionChannel3 = innerChannel as ISessionChannel<IOutputSession>;
                if (sessionChannel3 != null && sessionChannel3.Session != null)
                {
                    return sessionChannel3.Session.Id;
                }
            }
        }
        return null;
    }
}
于 2012-06-13T03:55:35.027 回答