Windows Azure Service Bus: Sending the message to queue and topic with JavaScript

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

IAs you probably know the easiest way to send the message to the queue or topic is to use .NET SDK. When using .NET SDK communication with Service Bus will be TCP on specific ports.
This protocol is called SBMP and stands fro native service message protocol. It is not some broadly use standard and for this reason is not very pushed form the marketing perspective. Another way to establish communication  would be AMQP
At the writing of this you cannot switch (downgrade) SBMP pr AMQP to HTTP protocol. Many developers think that this is possible. Unfortunately there is confusion around this, because Service Bus Relay features can downgrade to HTTP automatically if required TCP ports are blocked.
Fortunately, you can use HTTP to communicate with the Service Bus. In this post I will provide some samples which show how to do that. 

Prerequisites

Before you start with this example you will have to create one queue and one topic. But it is more interesting and more complicate to prepare Share Access Signatures. In other words you will have to create Access Rules and apply them to your entities (Queue and Topic). In my example the Java Script code will be shown which auth authenticate by using Shared Access Signature and not by using of Access Control Service.

The Share Access Signature token will look like:

image

You use following code to create the SAS Key with name ‘demouser1_can_Send

private static void createSaskey()
{
           
NamespaceManager namespaceManager =    
            NamespaceManager
.CreateFromConnectionString(m_ConnStr);

           
string qName = "hello/samplequeue";

           
string key1 = SharedAccessAuthorizationRule.GenerateRandomKey(); 
           
if (namespaceManager.QueueExists(qName))
                namespaceManager.DeleteQueue(qName);

           
QueueDescription qDesc1 = new QueueDescription(qName);

            qDesc1.Authorization.Add(
new SharedAccessAuthorizationRule
            (
"demouser1_can_Send", key1, new AccessRights[]
            {
AccessRights.Send })); 

}

After you execute this code, be sure that you make a copy of the ‘key1”.

Sending of a message to the queue/topic

First of all you will need a function which will create the token form key value (key1) and key name (demouser_can_send).
Missing encoding function can be found here.

    var m_ServiceNamespace = “yournamespace”;
    var m_SasKey = "…ErXlL6jg7P6dFA="; //paste here key1        
   
var m_SasKeyName = "demouser1_can_Send";

 
// Function which creates the Service Bus SAS token.
        var getToken = function (entityPath) {

       
var uri = "http://" + m_ServiceNamespace +
       
".servicebus.windows.net/" + entityPath;

       
var endocedResourceUri = encodeURIComponent(uri);

       
var t0 = new Date(1970, 1, 1, 0, 0, 0, 0);
       
var t1 = new Date();
       
var expireInSeconds =  + (31*24*3600) + 3600 +
       (((t1.getTime() - t0.getTime()) / 1000) | 0);

       
var plainSignature = utf8Encode(endocedResourceUri +
       
"\n" + expireInSeconds);

       
var hash = CryptoJS.HmacSHA256(plainSignature, m_SasKey);
       
var base64HashValue = CryptoJS.enc.Base64.stringify(hash);

       
var token = "SharedAccessSignature sr=" + endocedResourceUri + "&sig=" +
        encodeURIComponent(base64HashValue) +
"&se=" + expireInSeconds + "&skn=" +
        m_SasKeyName;

       
return token;
    }

  
   
var utf8Encode = function (s) {
       
for (var c, i = -1, l = (s = s.split("")).length,
            o = String.fromCharCode; ++i < l;
            s = (c = s.charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) +
            o(0x80 | (c & 0x3f)) : s
        );
       
return s.join("");
    }

 

Just to send a POST request to some endpoint is not a big deal. Unfortunately in our case, we have to be aware of CORS issue.
When you start to execute the JavaScript code, the JS file containing the code it downloaded from some Web site like contoso.com/mycode.js.
However Service Bus is hosted on domain servicebus.windows.net, which is a different one. In this case you will run into CORS issue.
Following code shows how to send the message to service bus queue by handling of CORS issue.


        // Sends the message to the queue.
        sendMessage:
function (entityName, body, contentType, callback) {
           
var securityToken = getToken(entityName);
           
var entityUri = "https://" + m_ServiceNamespace + "." +    
            this
.environment  + "/" + entityName;
           
var sendUri = entityUri + "/messages/?timeout=60";
           
var xmlHttpRequest = new XMLHttpRequest();

            xmlHttpRequest.open(
"POST", sendUri, true);
            xmlHttpRequest.setRequestHeader(
'Content-Type', contentType);
            xmlHttpRequest.setRequestHeader(
"Authorization", securityToken);
           
            xmlHttpRequest.onreadystatechange =
function () {

               
if (this.readyState == 4) {

                   
var messagingResult;

                 
  if (this.status == 201) {
                        messagingResult =
new MessagingResult("Success",
                        this
.status, null, this.response);
                    }
                   
else {
                        messagingResult =
new MessagingResult("Failure",
                        this
.status, null, this.response);
                    }

                   
if(callback != null)
                        callback(messagingResult);
                }
            };

            xmlHttpRequest.send(body);
        },

Assuming that the code shown above is packaged in some library, following demonstrate how to send the message.
The instance of the helper library is SB.

 
            $("#btnSend").click(function () {
               
               
var msg = { "message": txtMsg.value, "id": 1234};
           
                SB.sendMessage(topicOrqueuePath, JSON.stringify(msg),
               
"application/json", function (messagingResult) {
                
                    $(
"#result").html(messagingResult.body);
               });
            });


Posted Mar 18 2014, 07:46 PM by Damir Dobric

Comments

Damir Dobric Posts wrote Microsoft Azure Service Bus: PeekAndLock Messages with JavaScript
on 03-29-2014 13:31

This post is the third one of my Service Bus JavaScript posts. Episode I  - Receiving of Messages

Damir Dobric Posts wrote Microsoft Azure Service Bus: PeekAndLock Messages with JavaScript
on 03-29-2014 17:03

This post is the third one of my Service Bus JavaScript posts. Episode I  - Receiving of Messages

Bill Harts wrote re: Windows Azure Service Bus: Sending the message to queue and topic with JavaScript
on 04-06-2014 22:31

Damir,

Thanks for posting this stuff.  I think there's a small problem with your GetToken function in Javascript.  You are calculating the time of expiration as:

var expireInSeconds = +(31 * 24 * 3600) + 3600 + (((t1.getTime() - t0.getTime()) / 1000) | 0);

which seems a bit strange.  I think it works for you because you're in a time zone ahead of UTC. But for those of us in the rest of the world (like New York CIty), I think you need something like this:

expireInSeconds = (Date.now() / 1000) + 3600;

Bill

developers.de is a .Net Community Blog powered by daenet GmbH.