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

行動 WCF 實戰:使用 .NET Compact Framework 3.5 郵件傳輸建立 IM 應用程式

     編輯:關於.NET

行動裝置尋址困難,傳統輪詢方式影響伺服器擴展性與電池壽命。.NET Compact Framework 3.5 引入兩大郵件傳輸繫結元素 WindowsMobileMailTransport 與 ExchangeWebServiceMailTransport,善用 Exchange 郵件佇列特性實現真正的訊息推送,解決裝置尋址、連線維持、離線訊息暫存等難題。

郵件傳輸核心特性

  • 跨平台互通:裝置間、桌面間、裝置對桌面透明通訊
  • 通道隔離:郵件主旨含通道名稱,多應用共用信箱互不干擾
  • DirectPush 整合:支援 Exchange DirectPush 即時推送至 Windows Mobile
  • 單向訊息模式:適合 IM、通知等非請求-回覆場景
  • 需 Exchange Server 2007:目前唯一支援郵件伺服器

開發環境建置

  1. Visual Studio 2008 + Windows Mobile 6 Professional SDK
  2. .NET Compact Framework 3.5
  3. Windows Mobile Device Center 6.1 / ActiveSync 4.5
  4. 裝置/模擬器配置 Exchange 郵件帳戶

裝置端應用程式開發

必要組件參考

System.ServiceModel.dll
System.Runtime.Serialization.dll
Microsoft.ServiceModel.Channels.Mail.dll
Microsoft.ServiceModel.Channels.Mail.WindowsMobile.dll

自訂 XmlObjectSerializer (Compact WCF 缺少 DataContractSerializer)

class MessageSerializer : XmlObjectSerializer {
    XmlSerializer serializer;
    public MessageSerializer(Type type) { serializer = new XmlSerializer(type); }
    public override void WriteObject(XmlDictionaryWriter writer, object graph) 
        => serializer.Serialize(writer, graph);
    public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) 
        => serializer.Deserialize(reader);
}

通用 Messaging<T> 類別 (共用程式碼)

using Microsoft.ServiceModel.Channels.Mail;

class Messaging<T> {
    public delegate void IncomingMessageCallback(T body);
    public const string DeviceToDesktopChannel = "toDesktop";
    public const string DesktopToDeviceChannel = "toDevice";

    public Messaging(MailBindingBase binding, string sendChannel, string listenChannel, 
                     IncomingMessageCallback callback) { /* 建立通道、啟動接收迴圈 */ }
    
    public void SendMessage(string recipient, T body) { /* 發送郵件訊息 */ }
    public void Close() { /* 關閉通道 */ }
}

裝置端 UI 與初始化

// Form1.cs
Messaging<string> messaging;

void Form1_Load() {
    messaging = new Messaging<string>(
        new WindowsMobileMailBinding(),
        Messaging<string>.DeviceToDesktopChannel,  // 發送通道
        Messaging<string>.DesktopToDeviceChannel,   // 接收通道
        incomingMessage);
}

void sendMenuItem_Click(object sender, EventArgs e) {
    messaging.SendMessage(toTextBox.Text, messageTextBox.Text);
    messageTextBox.Text = "";
}

void incomingMessage(string message) {
    if (InvokeRequired) {
        Invoke((Messaging<string>.IncomingMessageCallback)incomingMessage, message);
    } else {
        historyTextBox.Text += message + Environment.NewLine;
        historyTextBox.ScrollToCaret();
    }
}

void Form1_Closed(object sender, EventArgs e) => messaging.Close();

桌面端 WPF 應用程式開發

組件參考 (差異在 Mail 傳輸)

Microsoft.ServiceModel.Channels.Mail.ExchangeWebService.dll

共用程式碼連結

將 MessageSerializer.cs、Messaging.cs 以「加入現有項目 → 連結」方式加入桌面專案。

桌面端初始化 (通道順序對調)

Messaging<string> messaging;
readonly Uri exchangeUrl = new Uri("https://mail.wingtiptoys.com");

public Window1() {
    InitializeComponent();
    var binding = new ExchangeWebServiceMailBinding(exchangeUrl, null); // Windows 整合驗證
    ((ExchangeWebServiceMailTransport)binding.Transport).ServerQueryInterval = 2000; // 2秒輪詢
    
    messaging = new Messaging<string>(
        binding,
        Messaging<string>.DesktopToDeviceChannel,  // 發送通道 (對調)
        Messaging<string>.DeviceToDesktopChannel,   // 接收通道 (對調)
        incomingMessage);
}

void Window_Closed(object sender, EventArgs e) => messaging.Close();

WPF 異步 UI 更新

void incomingMessage(string message) {
    if (historyBox.CheckAccess()) {
        historyBox.AppendText(message + Environment.NewLine);
        historyBox.ScrollToEnd();
    } else {
        historyBox.Dispatcher.Invoke(DispatcherPriority.Normal, 
            (Messaging<string>.IncomingMessageCallback)incomingMessage, message);
    }
}

執行與除錯要點

  • 部署裝置應用至已配置郵件的模擬器/實體裝置
  • 雙專案同時啟動偵錯
  • 雙方輸入相同 Exchange 信箱地址
  • 訊息流向:SOAP 封裝 → 發件箱 → Exchange → 收件箱 → 依通道主旨過濾 → 反序列化 → UI 顯示
  • 常見問題:通道名稱不符、同步未啟動、防火牆阻擋、後台執行緒例外未捕獲

呼叫 WCF 服務 (NetCFSvcUtil.exe)

.NET CF 3.5 PowerToys 提供 NetCFSvcUtil.exe 產生 Proxy:

NetCFSvcUtil.exe https://localhost:53222/Service/Service.svc?wsdl
  • 服務需提供 basicHttpBinding 端點 (CF 不支援 wsHttpBinding)
  • 產生 Service.cs、CFClientBase.cs
  • 修改 EndpointAddress 為實際主機名稱 (非 localhost)
  • 呼叫方式與桌面 WCF 相同:client.GetData(5)

總結

郵件傳輸讓行動 WCF 突破尋址限制,實現高效能、低耗電、離線可靠的訊息推送。搭配 NetCFSvcUtil 可輕鬆消費標準 WCF 服務,大幅降低行動開發門檻。

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