1

WCFで状態を管理するための最もスケーラブルな方法は何ですか。

セッションを示すために必要な変数は1つだけで、MSSQLでセッションに関連する情報を管理します。セッションがいつ終了するかを知る必要はありません。1日1回、古いセッションをすべてクリアします。

SessionIDはその変数のようです。

スケールについては、コンストラクターが空であるため、PerCallを使用しています。セッションごとに必要だとは思いません。

私の単純なEightBallテストでは、セッションを表すSessionIDを取得しています。しかし、私は1つのボックスでテストしているだけです。

私が心配しているのは、ReliableSessionBindingElementをオンに設定する必要があるドキュメントがいくつか表示され、デフォルトでオフになっていることです。

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種類のセッションをサポートしており、信頼できるセッションはそのうちの1つにすぎません。したがって、セッションを有効にするためにsetReliableSessionBindingElementをオンにする必要はありません。他のセッションタイプを使用できます。

WS-ReliableMessaging仕様を実装するはSystem.ServiceModel.Channels.ReliableSessionBindingElement、メッセージが順番に1回だけ配信される信頼性の高いセッションをサポートし、メッセージが会話中に複数のノードを通過する場合でも信頼性を高めます。

実際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コードがセッションID以外のセッションデータに依存しない場合は、これが正しい選択です。セッションIDはWCFメッセージの一部であるため、InstanceContext要求を処理するために必要な期間より長く保持する必要はありません。

別の質問:

SessionIDは、次の構成でセッションの信頼できるインジケーターになりますか?

答えはイエスです。以下は、プロパティのリバースエンジニアリングされたコードですSystem.ServiceModel.OperationContext.SessionId。ご覧SessionIdのとおり、がnullでない場合にのみ、からロードされChannel.Session、空ではないSessionId値が返されSessionます。

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 に答える