首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 會話管理:SessionMode、IsInitiating/IsTerminating 與 InstanceContextMode.PerSession 實戰

     編輯:關於.NET

WCF 會話 提供跨多次呼叫的狀態保持機制。透過 SessionMode、IsInitiating/IsTerminating 與 InstanceContextMode.PerSession,可精確控制會話生命週期與狀態範圍。

會話協定層級設定

ServiceContract.SessionMode

OperationContract 生命週期控制

值說明
Allowed (預設)綁定支援會話則使用,不支援則不使用
Required強制要求會話綁定,否則擲出例外
NotAllowed禁止會話
屬性說明
IsInitiating標記啟動會話的操作 (預設 true)
IsTerminating標記結束會話的操作 (預設 false)

服務端實作

契約定義

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IHello {
    [OperationContract(IsInitiating = true, IsTerminating = false)]
    void StartSession();

    [OperationContract(IsInitiating = false, IsTerminating = true)]
    void StopSession();

    [OperationContract(IsInitiating = false, IsTerminating = false)]
    int Counter();

    [OperationContract(IsInitiating = false, IsTerminating = false)]
    string GetSessionId();
}

實作:PerSession 實例模式

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Hello : IHello {
    private int _counter;

    public void StartSession() => _counter = 0;
    public void StopSession() => _counter = 0;
    public int Counter() => ++_counter;
    public string GetSessionId() => OperationContext.Current.SessionId;
}

綁定與安全會話設定

wsHttpBinding 支援安全會話與可靠會話:

<wsHttpBinding>
  <binding name="SessionManagementBindingConfiguration" receiveTimeout="00:00:10">
    <reliableSession enabled="true" />
    <security>
      <message establishSecurityContext="true" /> <!-- WS-SecureConversation -->
    </security>
  </binding>
</wsHttpBinding>
  • receiveTimeout:非活動逾時 (此處 10 秒),相當於 Session 過期時間
  • reliableSession:WS-ReliableMessaging 可靠會話
  • establishSecurityContext:WS-SecureConversation 安全會話,建立安全內容權杖 (SCT)

客戶端使用

ASP.NET 網頁保持 Proxy

public partial class InstanceMode_Hello : Page {
    SessionManagemenSvc.HelloClient _proxy;

    protected void Page_Load(object sender, EventArgs e) {
        if (Session["proxy"] == null)
            Session["proxy"] = new SessionManagemenSvc.HelloClient();
        _proxy = Session["proxy"] as SessionManagemenSvc.HelloClient;
    }

    protected void btnStartSession_Click(object sender, EventArgs e) {
        _proxy.StartSession();
    }

    protected void btnCounter_Click(object sender, EventArgs e) {
        ScriptManager.RegisterStartupScript(this, GetType(), "js",
            $"alert('計數器:{_proxy.Counter()}')", true);
    }

    protected void btnGetSessionId_Click(object sender, EventArgs e) {
        ScriptManager.RegisterStartupScript(this, GetType(), "js",
            $"alert('SessionId:{_proxy.GetSessionId()}')", true);
    }

    protected void btnStopSession_Click(object sender, EventArgs e) {
        _proxy.StopSession();
    }
}

客戶端綁定設定

<wsHttpBinding>
  <binding name="SessionManagementBindingConfiguration">
    <reliableSession enabled="true" />
    <security>
      <message establishSecurityContext="true" />
    </security>
  </binding>
</wsHttpBinding>

運作流程

  1. 點擊 StartSession → 呼叫 StartSession(),初始化計數器,建立會話
  2. 多次點擊 Counter → 同一 Session 內計數器遞增 (1, 2, 3...)
  3. 點擊 GetSessionId → 顯示 WCF 產生的 Session ID (GUID 格式)
  4. 點擊 StopSession → 呼叫 StopSession(),結束會話,後續呼叫將失敗
  5. 超過 receiveTimeout (10 秒) 無活動 → 伺服器自動終止會話

會話 vs 實例模式關係

InstanceContextMode會話行為
PerCall不支援會話狀態 (每呼叫新實例)
PerSession每個 Session 一個實例,支援會話狀態
Single全域單一實例,所有 Session 共享 (需自行隔離狀態)

最佳實務

  • 明確設定 SessionMode.Required 確保綁定支援
  • 使用 IsInitiating/IsTerminating 定義明確的會話邊界
  • 設定合理的 receiveTimeout 避免資源洩漏
  • 客戶端妥善管理 Proxy 生命週期 (如 ASP.NET 存入 Session)
  • 考慮使用 wsHttpBinding 或 netTcpBinding 獲得完整會話支援

WCF 會話機制讓無狀態的 Web 服務也能輕鬆實現有狀態的商務流程,是建構企業級應用的重要基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved