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

WCF 實戰教學 (5):服務裝載策略全解析 — 以 Windows Service 裝載為例

     編輯:關於.NET

前言

WCF 服務必須在「宿主」中執行。常見裝載方式有四種:IIS / WAS (Windows Process Activation Service) / Windows Service / 自我裝載 (Self-Host / Console/WinForm/WPF)。各有優劣,選型需依部署環境、啟動需求、管理便利性決定。本篇以 Windows Service 裝載 為主軸,完整示範從服務安裝、啟動、WCF 整合到用戶端呼叫的端到端流程。

四種裝載方式快速比較

裝載方式啟動模式進程管理適用場景缺點
IIS / WAS訊息觸發啟動 (按需)IIS/WAS 自動管理回收、健康監控Web 應用、HTTP/HTTPS 服務、需高可用性僅支援 HTTP/Net.Tcp (WAS);部署相對複雜
Windows Service開機自動/手動啟動SCM (Service Control Manager) 管理長期運行、非 HTTP 協定 (TCP, Named Pipe)、需開機即服務需管理員權限安裝;手動更新較麻煩
自我裝載應用程式啟動時手動 Open()開發者自行控制開發測試、桌面應用內嵌服務、簡單部署無自動回收、健康監控;生產環境較少用

完整實作:Windows Service 裝載 WCF

1. 服務契約與實作 (共用類別庫)

// IHello.cs
using System.ServiceModel;

namespace WCF.ServiceLib.Sample
{
    [ServiceContract]
    public interface IHello
    {
        [OperationContract]
        string SayHello(string name);
    }
}

// Hello.cs
namespace WCF.ServiceLib.Sample
{
    public class Hello : IHello
    {
        public string SayHello(string name) => $"Hello: {name}";
    }
}

2. Windows Service 專案 (宿主)

ProjectInstaller.cs - 安裝程式

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WCF.ServiceHostByWindowsService.Sample
{
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        public ProjectInstaller()
        {
            var process = new ServiceProcessInstaller { Account = ServiceAccount.LocalSystem };
            var service = new ServiceInstaller
            {
                ServiceName = "WCF.ServiceHostByWindowsService",
                DisplayName = "WCF 服務宿主範例",
                Description = "示範 WCF 服務裝載於 Windows Service",
                StartType = ServiceStartMode.Automatic
            };
            Installers.AddRange(new Installer[] { process, service });
        }
    }
}

WindowsService.cs - 服務主程式

using System;
using System.ServiceModel;
using System.ServiceProcess;
using WCF.ServiceLib.Sample;

namespace WCF.ServiceHostByWindowsService.Sample
{
    public class WindowsService : ServiceBase
    {
        private ServiceHost _host;

        public static void Main() => ServiceBase.Run(new WindowsService());

        public WindowsService() => ServiceName = "WCF.ServiceHostByWindowsService";

        protected override void OnStart(string[] args)
        {
            _host?.Close();
            _host = new ServiceHost(typeof(Hello));
            _host.Open(); // 依 App.config 開啟端點
            
            // 可選:訂閱 ServiceHost 事件進行監控
            _host.Faulted += (s, e) => 
            {
                // 記錄錯誤、嘗試重啟等
                System.Diagnostics.EventLog.WriteEntry("WCFHost", "ServiceHost 進入 Faulted 狀態", System.Diagnostics.EventLogEntryType.Error);
            };
        }

        protected override void OnStop()
        {
            _host?.Close();
            _host = null;
        }
    }
}

3. App.config - 服務端點與行為設定

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WCF.ServiceLib.Sample.Hello" behaviorConfiguration="SampleBehavior">
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="WCF.ServiceLib.Sample.IHello" />
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:11233/ServiceHostByWindowsService/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="SampleBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

4. 安裝與啟動步驟

  1. 以系統管理員身分開啟 Visual Studio Developer Command Prompt
  2. 切換至專案輸出目錄 (含 InstallUtil.exe)
  3. 執行安裝:InstallUtil.exe WCF.ServiceHostByWindowsService.exe
  4. 開啟「服務」(services.msc),找到 WCF 服務宿主範例,啟動它
  5. 瀏覽器輸入 https://localhost:11233/ServiceHostByWindowsService/ 驗證 WSDL 是否正常

5. 用戶端呼叫 (ASP.NET Web Form)

// Hello.aspx.cs
public partial class Hosting_Hello : System.Web.UI.Page
{
    protected void btnSayHello_Click(object sender, EventArgs e)
    {
        var proxy = new HostingByWindowsService.HelloClient();
        var result = proxy.SayHello(txtName.Text);
        ClientScript.RegisterStartupScript(GetType(), "msg", $"alert('{result}');", true);
        proxy.Close();
    }
}

用戶端 Web.config

<client>
  <endpoint address="https://localhost:11233/ServiceHostByWindowsService/"
            binding="wsHttpBinding"
            contract="Sample.IHello" />
</client>

進階主題:生產環境強化建議

1. 服務復原設定

在 `ProjectInstaller` 中或透過 `sc.exe` 設定失敗自動重啟:

sc failure "WCF.ServiceHostByWindowsService" reset= 86400 actions= restart/60000/restart/120000/restart/180000

2. 自訂事件日誌來源

if (!EventLog.SourceExists("WCFHost"))
    EventLog.CreateEventSource("WCFHost", "Application");

3. 支援多種繫結同時對外

在同一 `ServiceHost` 新增多個 Endpoint:

_host.AddServiceEndpoint(typeof(IHello), new NetTcpBinding(), "net.tcp://localhost:54321/Hello");
_host.AddServiceEndpoint(typeof(IHello), new NetNamedPipeBinding(), "net.pipe://localhost/Hello");

4. 優雅關閉與健康檢查

  • 實作 `ICommunicationObject` 事件處理,記錄狀態變更
  • 提供專用健康檢查端點 (如 HTTP GET /health) 供負載平衡器探測

常見問題排查

  1. 安裝失敗「存取被拒」:請確認以管理員身分執行 InstallUtil
  2. 服務啟動後立即停止:檢查 Event Viewer → Application Log,常見為連接埠衝突、BaseAddress ACL 未授權 (需 `netsh http add urlacl`)
  3. 防火牆阻擋:開放對應連接埠 (範例 11233, 54321) 的輸入規則
  4. 更新服務程式碼:停止服務 → 覆蓋檔案 → 啟動服務 (或重新 InstallUtil /u 再安裝)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved