来自Xamarin Forms PCL的Azure ServiceBus

5

如何通过Xamarin Forms PCL实现Azure Service Bus的经纪人消息传递...是否有SDK、库或插件?如果有手动创建经纪人消息的方法,我想可以使用HttpClient和REST API来完成...


你的目标是针对 Windows、Android 和 iOS 吗? - Thomas
目前只针对iOS和Android。 - Brooks Clark
1个回答

5

我终于有了一种可行的方法,可以通过HttpClient从Xamarin PCL向Azure Service Bus队列发送消息!

导致解决方案难以找到的要点:

  • The nuget package for Microsoft.ServiceBus.Messaging will happily install, but has no exposure to the portable class.

  • WebClient examples abound, but there is no webclient available in the PCL!

  • PCL has no native crypto for HMACSHA256 for Shared Access Signature tokens. Get the PCLCrypto package from nuget.
  • Some documentation says request headers of Content-Type : application/atom+xml;type=entry;charset=utf-8, and BrokerProerties are required. Ain't so!
  • The path to post to is: 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);
    }
    

    }


你好,能否请分享一下你的导入/使用语句? - masood elsad
使用 Newtonsoft.Json; 使用 PCLCrypto; 使用 System; 使用 System.Globalization; 使用 System.Net; 使用 System.Net.Http; 使用 System.Net.Http.Headers; 使用 System.Text; 使用 System.Threading.Tasks; - LDJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接