来自 Xamarin Forms 的 Azure ServiceBus PCL
Azure ServiceBus from Xamarin Forms PCL
如何通过 Azure 服务总线从 Xamarin Forms 完成代理消息传递 PCL...是否有 SDK、库或插件?如果有办法手动滚动代理消息,我想它可以通过 HttpClient 和 REST API ...
来完成
我终于有了一个工作方法,可以将消息从 Xamarin PCL post 发送到 Azure 服务总线 Queue!执行此操作的方法是通过 HttpClient。
使解决方案难以捉摸的陷阱:
Microsoft.ServiceBus.Messaging 的 nuget 包将愉快地安装,但没有暴露给便携式 class。
WebClient的例子比比皆是,但是没有可用的webclient
PCL!
- PCL 没有用于共享访问签名的 HMACSHA256 本机加密
令牌。从 nuget 获取 PCLCrypto 包。
- 一些文档说请求 headers of Content-Type : application/atom+xml;type=entry;charset=utf-8,并且 BrokerProerties 是必需的。不是这样的!
到 post 的路径是:BaseServiceBusAddress + queue + "/messages"
public const string ServiceBusNamespace = [YOUR SERVICEBUS NAMESPACE];
public const string BaseServiceBusAddress = "https://" + ServiceBusNamespace + ".servicebus.windows.net/";
/// <summary>
/// The get shared access signature token.
/// </summary>
/// <param name="sasKeyName">
/// The shared access signature key name.
/// </param>
/// <param name="sasKeyValue">
/// The shared access signature key value.
/// </param>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public static string GetSasToken(string sasKeyName, string sasKeyValue)
{
var expiry = GetExpiry();
var stringToSign = WebUtility.UrlEncode(BaseServiceBusAddress ) + "\n" + expiry;
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
var hasher = algorithm.CreateHash(Encoding.UTF8.GetBytes(sasKeyValue));
hasher.Append(Encoding.UTF8.GetBytes(stringToSign));
var mac = hasher.GetValueAndReset();
var signature = Convert.ToBase64String(mac);
var sasToken = string.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", WebUtility.UrlEncode(baseAddress), WebUtility.UrlEncode(signature), expiry, sasKeyName);
return sasToken;
}
/// <summary>
/// Posts an order data transfer object to queue.
/// </summary>
/// <param name="orderDto">
/// The order data transfer object.
/// </param>
/// <param name="serviceBusNamespace">
/// The service bus namespace.
/// </param>
/// <param name="sasKeyName">
/// The shared access signature key name.
/// </param>
/// <param name="sasKey">
/// The shared access signature key.
/// </param>
/// <param name="queue">
/// The queue.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
public static async Task<HttpResponseMessage> PostOrderDtoToQueue(OrderDto orderDto, string serviceBusNamespace, string sasKeyName, string sasKey, string queue)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(BaseServiceBusAddress);
client.DefaultRequestHeaders.Accept.Clear();
var token = GetSasToken(sasKeyName, sasKey);
client.DefaultRequestHeaders.Add("Authorization", token);
HttpContent content = new StringContent(JsonConvert.SerializeObject(orderDto), Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var path = BaseServiceBusAddress + queue + "/messages";
return await client.PostAsync(path, content);
}
}
/// <summary>
/// Gets the expiry for a shared access signature token
/// </summary>
/// <returns>
/// The <see cref="string" /> expiry.
/// </returns>
private static string GetExpiry()
{
var sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
return Convert.ToString((int)sinceEpoch.TotalSeconds + 3600);
}
}
如何通过 Azure 服务总线从 Xamarin Forms 完成代理消息传递 PCL...是否有 SDK、库或插件?如果有办法手动滚动代理消息,我想它可以通过 HttpClient 和 REST API ...
来完成我终于有了一个工作方法,可以将消息从 Xamarin PCL post 发送到 Azure 服务总线 Queue!执行此操作的方法是通过 HttpClient。
使解决方案难以捉摸的陷阱:
Microsoft.ServiceBus.Messaging 的 nuget 包将愉快地安装,但没有暴露给便携式 class。
WebClient的例子比比皆是,但是没有可用的webclient PCL!
- PCL 没有用于共享访问签名的 HMACSHA256 本机加密 令牌。从 nuget 获取 PCLCrypto 包。
- 一些文档说请求 headers of Content-Type : application/atom+xml;type=entry;charset=utf-8,并且 BrokerProerties 是必需的。不是这样的!
到 post 的路径是:BaseServiceBusAddress + queue + "/messages"
public const string ServiceBusNamespace = [YOUR SERVICEBUS NAMESPACE]; public const string BaseServiceBusAddress = "https://" + ServiceBusNamespace + ".servicebus.windows.net/"; /// <summary> /// The get shared access signature token. /// </summary> /// <param name="sasKeyName"> /// The shared access signature key name. /// </param> /// <param name="sasKeyValue"> /// The shared access signature key value. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string GetSasToken(string sasKeyName, string sasKeyValue) { var expiry = GetExpiry(); var stringToSign = WebUtility.UrlEncode(BaseServiceBusAddress ) + "\n" + expiry; var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256); var hasher = algorithm.CreateHash(Encoding.UTF8.GetBytes(sasKeyValue)); hasher.Append(Encoding.UTF8.GetBytes(stringToSign)); var mac = hasher.GetValueAndReset(); var signature = Convert.ToBase64String(mac); var sasToken = string.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", WebUtility.UrlEncode(baseAddress), WebUtility.UrlEncode(signature), expiry, sasKeyName); return sasToken; } /// <summary> /// Posts an order data transfer object to queue. /// </summary> /// <param name="orderDto"> /// The order data transfer object. /// </param> /// <param name="serviceBusNamespace"> /// The service bus namespace. /// </param> /// <param name="sasKeyName"> /// The shared access signature key name. /// </param> /// <param name="sasKey"> /// The shared access signature key. /// </param> /// <param name="queue"> /// The queue. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public static async Task<HttpResponseMessage> PostOrderDtoToQueue(OrderDto orderDto, string serviceBusNamespace, string sasKeyName, string sasKey, string queue) { using (var client = new HttpClient()) { client.BaseAddress = new Uri(BaseServiceBusAddress); client.DefaultRequestHeaders.Accept.Clear(); var token = GetSasToken(sasKeyName, sasKey); client.DefaultRequestHeaders.Add("Authorization", token); HttpContent content = new StringContent(JsonConvert.SerializeObject(orderDto), Encoding.UTF8); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var path = BaseServiceBusAddress + queue + "/messages"; return await client.PostAsync(path, content); } } /// <summary> /// Gets the expiry for a shared access signature token /// </summary> /// <returns> /// The <see cref="string" /> expiry. /// </returns> private static string GetExpiry() { var sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1); return Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); }
}