介紹
重新想象 Windows 8 Store Apps 之 後台任務
控制通道(ControlChannel)
示例
1、客戶端與服務端做 ControlChannel 通信的關鍵代碼
ControlChannelHelper/AppContext.cs
/*
* 本例通過全局靜態變量來實現 app 與 task 的信息共享,以便後台任務可以獲取到 app 中的相關信息
*
* 注:
* 也可以通過 Windows.ApplicationModel.Core.CoreApplication.Properties 保存數據,以實現 app 與 task 的信息共享
*/
using System.Collections.Concurrent;
using Windows.Networking.Sockets;
namespace ControlChannelHelper
{
public class AppContext
{
/// <summary>
/// 從 ControlChannel 接收到的數據
/// </summary>
public static ConcurrentQueue<string> MessageQueue = new ConcurrentQueue<string>();
/// <summary>
/// 客戶端 socket
/// </summary>
public static StreamSocket ClientSocket;
}
}
ControlChannelHelper/SocketControlChannel.cs
/*
* 實現一個 socket tcp 通信的 ControlChannel,client 將在此 ControlChannel 中實時接收數據
*
* 注:
* win8 client 和 socket server 不能部署在同一台機器上,否則會拋出異常:{參考的對象類型不支持嘗試的操作。 (異常來自 HRESULT:0x8007273D)}
*/
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Foundation;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
namespace ControlChannelHelper
{
public class SocketControlChannel : IDisposable
{
// ControlChannel
public ControlChannelTrigger Channel { get; set; }
// 客戶端 socket
private StreamSocket _socket;
// 用於發送數據
private DataWriter _dataWriter;
// 用於接收數據
private DataReader _dataReader;
// 向服務端發送心跳的間隔時間,單位為分鐘,最小 15 分鐘
private uint _serverKeepAliveInterval = 15;
// ControlChannel 的標識
private string _channelId = "myControlChannel";
public SocketControlChannel()
{
}
public async Task<string> CreateChannel()
{
Dispose();
try
{
// 實例化一個 ControlChannel
Channel = new ControlChannelTrigger(_channelId, _serverKeepAliveInterval, ControlChannelTriggerResourceType.RequestHardwareSlot);
}
catch (Exception ex)
{
Dispose();
return "控制通道創建失敗:" + ex.ToString();
}
// 注冊用於向服務端 socket 發送心跳的後台任務,需要在 manifest 中做相關配置
var keepAliveBuilder = new BackgroundTaskBuilder();
keepAliveBuilder.Name = "myControlChannelKeepAlive";
// 注:如果走的是 WebSocket 協議,則系統已經為其內置了發送心跳的邏輯,此處直接指定為 Windows.Networking.Sockets.WebSocketKeepAlive 即可
keepAliveBuilder.TaskEntryPoint = "BackgroundTaskLib.ControlChannelKeepAlive";
keepAliveBuilder.SetTrigger(Channel.KeepAliveTrigger); // 到了發送心跳的間隔時間時則觸發,本例是 15 分鐘
keepAliveBuilder.Register();
// 注冊用於向用戶顯示通知的後台任務,需要在 manifest 中做相關配置
// 查看本欄目
/*
* 用於向服務端 socket 發送心跳的後台任務
*
* 注:
* 如果走的是 WebSocket 協議,則系統已經為其內置了發送心跳的邏輯
* 只需要將 BackgroundTaskBuilder.TaskEntryPoint 設置為 Windows.Networking.Sockets.WebSocketKeepAlive 即可,而不需要再自定義此後台任務
*/
using ControlChannelHelper;
using System;
using Windows.ApplicationModel.Background;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
namespace BackgroundTaskLib
{
public sealed class ControlChannelKeepAlive : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
if (taskInstance == null)
return;
// 獲取 ControlChannel
// 查看本欄目