Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

WCFのセッション機能でステートフルなWebサービスを作成する

Webサービスは通常ステートレスですが、WCFのセッション機能を使うとステートフルなWebサービスを作成することができます。

検証環境

Visual Studio 2008 SP1、.NET Framework 3.5 SP1

WCFサービスプロジェクト

プロジェクトテンプレートは、[Web] - [WCFサービスアプリケーション]を選択します。

IService1.cs
using System.ServiceModel;

namespace WcfService3 {
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IService1 {
        /// <summary>
        /// セッションを開始します。
        /// </summary>
        /// <param name="clientName">クライアントの名前。</param>
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        void Initialize(string clientName);

        /// <summary>
        /// データを取得します。
        /// </summary>
        /// <returns>データ。</returns>
        [OperationContract(IsInitiating = false, IsTerminating = false)]
        string GetData();

        /// <summary>
        /// セッションを終了します。
        /// </summary>
        [OperationContract(IsInitiating = false, IsTerminating = true)]
        void Terminate();
    }
}
Service1.svc.cs
namespace WcfService3 {
    public class Service1 : IService1 {
        private string clientName;
        private int callCount = 0;

        #region IService1 メンバー

        public void Initialize(string clientName) {
            this.clientName = clientName;
        }

        public string GetData() {
            callCount++;
            return string.Format("クライアント名:{0} 呼び出し回数:{1}", this.clientName, this.callCount);
        }

        public void Terminate() {
        }

        #endregion
    }
}
Web.config

デフォルトのまま。

Webアプリケーションプロジェクト

プロジェクトテンプレートは、[Web] - [ASP.NET Webアプリケーションプロジェクト]を選択します。

サービス参照の追加

1.[参照設定]のコンテキストメニューから[サービス参照の追加]を選択します。
2.[探索]をクリックします。

3.[OK]をクリックします。

サービス参照が追加されます。

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div id="result" runat="server">
    
    </div>
    </form>
</body>
</html>
Default.aspx.cs
using System;
using WebApplication1.ServiceReference1;

namespace WebApplication1 {
    public partial class _Default : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            Service1Client clientHoge = new Service1Client();
            clientHoge.Initialize("Hoge");

            Service1Client clientFuga = new Service1Client();
            clientFuga.Initialize("Fuga");

            // HogeとFugaのGetDataをランダムに呼び出す。
            result.InnerHtml += clientHoge.GetData() + "<br />";
            result.InnerHtml += clientFuga.GetData() + "<br />";

            result.InnerHtml += clientHoge.GetData() + "<br />";
            result.InnerHtml += clientHoge.GetData() + "<br />";
            result.InnerHtml += clientHoge.GetData() + "<br />";

            result.InnerHtml += clientFuga.GetData() + "<br />";
            result.InnerHtml += clientFuga.GetData() + "<br />";

            result.InnerHtml += clientHoge.GetData() + "<br />";
            result.InnerHtml += clientFuga.GetData() + "<br />";

            clientHoge.Terminate();
            clientHoge.Close();

            clientFuga.Terminate();
            clientFuga.Close();
        }
    }
}
Web.config

デフォルトのまま。

実行結果


GetDataメソッドの呼び出し順と一致していますね、呼び出し回数も正しくインクリメントされています。

参考

セッションの使用
Windows Communication Foundation (WCF) アプリケーションでは、セッションがメッセージのグループを相互に関連付けて通信を行います。 WCF セッションは、ASP.NET アプリケーションで使用できるセッション オブジェクトとは異なるものであり、サポートされる動作と制御する方法が異なります。 ここでは、WCF アプリケーションのセッションで有効になる諸機能とそれらの使用方法について説明します。