如何通过Azure Service Bus从Xamarin Forms PCL完成代理消息传递...是否有SDK,库或插件?如果有办法手工推送代理消息,我想可以用HttpClient& REST API ......
答案 0 :(得分:5)
我终于有了一种从Xamarin PCL向Azure Service Bus Queue发布消息的工作方法!这样做的方法是通过HttpClient。
让解决方案变得难以捉摸的陷阱:
Microsoft.ServiceBus.Messaging的nuget包将很乐意安装,但不会暴露于便携式类。
WebClient示例比比皆是,但是没有可用的webclient PCL!
发布到的路径是: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);
}
}