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

WCF 雙工服務實現從 Web 推送訊息到 WinForms 桌面應用

     編輯:關於.NET

架構概覽

Web 發送介面 WinForms 接收介面

  • Web 端:訊息寫入 HttpRuntime.Cache
  • WCF 雙工服務:定時輪詢 Cache,透過 Callback Channel 推送至 WinForms
  • WinForms 端:實作 Callback 介面,接收訊息更新 UI

專案結構

專案結構

  • SendMessage.aspx:發送訊息頁面
  • ISendMessageService.cs / SendMessageService.svc:WCF 雙工服務定義與實作
  • GetMessageForm.cs:WinForms 接收視窗
  • MessageEntity.cs:訊息資料合約

核心代碼

資料合約

[DataContract]
public class MessageEntity {
    [DataMember] public string Content { get; set; }
}

服務合約與回呼合約

[ServiceContract(CallbackContract = typeof(ISendMessageServiceCallback))]
public interface ISendMessageService {
    [OperationContract(IsOneWay = true)] void GetMessage();
}

public interface ISendMessageServiceCallback {
    [OperationContract(IsOneWay = true)] void ReceiveMessage(MessageEntity messageEntity);
}

服務實作 (含 Timer 輪詢)

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class SendMessageService : ISendMessageService
{
    ISendMessageServiceCallback _callback;
    Timer _timer;
    Random _rnd = new Random();

    public void GetMessage()
    {
        _callback = OperationContext.Current.GetCallbackChannel();
        _timer = new Timer(PollCache, null, 3000, Timeout.Infinite);
    }

    void PollCache(object state)
    {
        var list = HttpRuntime.Cache["MessageEntityList"] as List;
        if (list != null && list.Count > 0)
        {
            var msg = list[0];
            list.RemoveAt(0);
            HttpRuntime.Cache["MessageEntityList"] = list;
            _callback.ReceiveMessage(msg);
        }
        _timer.Change(_rnd.Next(2000, 5000), Timeout.Infinite);
    }
}

Web.config 關鍵設定

<service behaviorConfiguration="WebApp.SendMessageServiceBehavior" name="WebApp.SendMessageService">
  <endpoint address="" binding="wsDualHttpBinding" contract="WebApp.ISendMessageService">
    <identity><dns value="localhost"/></identity>
  </endpoint>
  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

必須使用 wsDualHttpBinding 支援雙工通訊。

Web 端發送邏輯

protected void btnSend_Click(object sender, EventArgs e)
{
    var msg = new MessageEntity { Content = txtMessageContent.Text };
    var list = HttpRuntime.Cache["MessageEntityList"] as List ?? new List();
    list.Add(msg);
    HttpRuntime.Cache["MessageEntityList"] = list;
    lbCacheCount.Text = list.Count.ToString();
}

WinForms 端回呼實作

public partial class GetMessageForm : Form, ISendMessageServiceCallback
{
    SendMessageServiceClient _client;

    public GetMessageForm()
    {
        InitializeComponent();
        _client = new SendMessageServiceClient(new InstanceContext(this));
    }

    private void btnStartGet_Click(object sender, EventArgs e)
    {
        _client.GetMessage();
    }

    public void ReceiveMessage(MessageEntity messageEntity)
    {
        if (listbMessage.InvokeRequired)
            listbMessage.Invoke(new Action(() => listbMessage.Items.Add(messageEntity.Content)));
        else
            listbMessage.Items.Add(messageEntity.Content);
    }
}

部署步驟

  1. 建立 Web 專案部署 WCF 服務,確認 .svc 可正常瀏覽
  2. WinForms 專案「加入服務參考」指向服務 URL
  3. 啟動 Web 應用程式與 WinForms 應用程式
  4. 於 Web 頁面發送訊息 → WinForms 即時接收顯示

注意事項

  • wsDualHttpBinding 需要客戶端可對外開啟連接埠 (防火牆/NAT 環境需額外配置)
  • 生產環境建議使用 netTcpBinding + 雙工或 SignalR 等現代替代方案
  • Cache 非持久化,應用程式池回收會遺失訊息,正式專案請改用資料庫/訊息佇列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved