History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: AMQ-1377
Type: Improvement Improvement
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Jim Cook
Votes: 5
Watchers: 6
Operations

If you were logged in you would be able to see more operations.
ActiveMQ

amq.js should not have a dependency on prototype.js

Created: 04/Sep/07 06:58 AM   Updated: 10/Sep/08 05:13 AM
Component/s: Broker
Affects Version/s: 5.0.0
Fix Version/s: 5.3.0

Time Tracking:
Not Specified

File Attachments:
  Size
File amq.js 2008-06-12 11:03 PM Saira Gul 8 kb
File Licensed for inclusion in ASF works amq.js 2008-01-09 09:47 AM Dan Schooler 7 kb
File Licensed for inclusion in ASF works amq.js 2008-01-03 10:07 AM Dan Schooler 7 kb
Zip Archive Licensed for inclusion in ASF works amq_js.zip 2007-09-04 08:00 AM Jim Cook 45 kb


 Description  « Hide
amq.js uses a script loading technique to include behavior.js, prototype.js and _amq.js. The Behavior library is included only for the purposes of the chat client and is only GUI in nature, so that should go. Also, Prototype is included for its AJAX functionality, however everyone has their favorite javascript library and although I cut my teeth on prototype, I use jQuery now. I certainly don't want amq.js to include prototype when I have a perfectly good AJAX library already included in jQuery.

IMHO, amq.js should include only the functionality of client-side javascript-enabled JMS. The page author should include her AJAX library of choice (prototype, dojo, jquery, mootools, etc.) and an adapter class that allows amq.js to use the particular ajax library.



 All   Comments   Work Log   Change History   Subversion Commits   FishEye   Crucible      Sort Order: Ascending order - Click to sort in descending order
Jim Cook - 04/Sep/07 08:00 AM - edited
I have included an attachment containing the changes this issue describes.

The refactor is entirely client-side and the AjaxServlet and MessageListener Servlet have not been modified. The refactor breaks out prototype's AJAX handling from the core _amq.js file and replaces it with an adapter class. Also included is an adapter for jQuery. Here is a description of changes in each major file.

chat.html

  • No longer uses amq.js that loads _amq.js, prototype.js and behavior.js. SImple add amq.js which now contains the full client-side jms implementation that communicates with the AjaxServlet on the server.
  • Initialization code slightly different now. The chat event handlers and general initialization is now purposeful instead of triggered by a quirky poll handler.

amq.js

  • This file is a bit different. It has been reorganized to support a namespace and private/pubic properties and methods.
  • The batch process has been refactored from its reference counter implementation to a simple queue. I was experiencing bugs using the prior approach and this simpler approach seems to offer the same capabilities, especially since only one AJAX POST can be made to the server at a time. Please correct me if I am wrong or overlooked something.
  • The AJAX and logging functionality has been externalized to an adapter class.
  • Added some basic error recovery (reconnect), however this is an area where more improvement is needed.
  • Removed the addPollHandler functionality although it is trivial to add back. It was being misused (along with a 'first' boolean value and a jiggered timeout value) to initialize the chat.html page.

amq_xxx_adapter.js

  • These are the adapter files that externalize the AJAX call on behalf of the amq.js file.
  • They also can externalize logging, however they just log to Firebug right now.

Dan Schooler - 03/Oct/07 02:00 PM
The basic error recovery (reconnect) is a much needed feature.
My web clients have intermittent connectivity back to the server and it would be great if they would automatically recover instead of the user having to manually refresh the browser.

Dan Schooler - 03/Jan/08 10:07 AM
Automatically reconnect in the event of an error.

Also added an optional connectStatusHandler() method that will be called with a "true" parameter on success and "false" on error. This can be used to drive a connection status indicator on the client.


Dan Schooler - 09/Jan/08 09:47 AM
Workaround bug with IE6 caching the GET requests by adding unique dummy parameters of timestamp and random number.

Saira Gul - 12/Jun/08 02:49 AM
Hi dan
i m facing the same issue that is if the network connection drops temporarily (such as by unplugging the network cable for a minute and then plugging it back in) the clients just stop receiving messages and never resume until the browser is reloaded.

i am using following amq.js file in my application

var _AMQ_INCLUDE = {
Version: 'AMQ JS',
script: function(libraryName) { document.write('<script type="text/javascript" src="'+libraryName+'"></script>'); },
load: function() {
var scriptTags = document.getElementsByTagName("script");
for(var i=0;i<scriptTags.length;i++) {
if(scriptTags[i].src && scriptTags[i].src.match(/amq\.js$/)) { var path = scriptTags[i].src.replace(/amq\.js$/,''); this.script(path + 'prototype.js'); this.script(path + 'behaviour.js'); this.script(path + '_amq.js'); // this.script(path + 'scriptaculous.js'); break; }
}
}
}

_AMQ_INCLUDE.load();

please give me any suggestion vat should i do in this respect ao that my application works fine??

Thanks
Saira


Dan Schooler - 12/Jun/08 10:23 AM
The most recent version of amq.js that I had attached should work fine for that.
We have been using it in our production application for nearly 6 months now.
Just download the .zip that Jim Cook had attached and then download my most recent amq.js (with the IE6 workaround) and overwrite the one from the .zip

You will need to make sure that your application explicitly includes the customized files.
The autoloader script (that you had attached) won't work for this.
Your HTML should have something like this:

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="amq_prototype_adapter.js"></script>
<script type="text/javascript" src="amq.js"></script>

So that it will explicitly include the customized files in the proper order....


Saira Gul - 12/Jun/08 11:03 PM
hi Dan!!

i am using your latest updated amq.js file with cook's prototype file and eliminate the amq_prototype_adapter.js.. the problem is that when i want to call AjaxServlet with the following code

Ajax.Request(uri, { method: 'post', postBody: body, onSuccess: org.activemq.Amq.endBatch});

then the AjaxServlet does not get called? Could u plz tell me any solution and review my attached amq.js?

Thanks


Dan Schooler - 13/Jun/08 07:34 AM - edited
Jim's modified files require either the amq_jquery_adapter or the amq_prototype_adapter, which in turn require jquery or prototype, respectively. The include order of the .js files is also important. You must first include prototype or jquery, then include the respective adapter, then include the modified amq.js

If you eliminate the amq_prototype_adapter.js completely then amq.js will definitely not work because it requires one of the adapters to use the appropriate AJAX library.

I would suggest that you install the Firebug plugin in your Firefox web browser, set some breakpoints in the javascript code and step through it to see what is happening.


Saira Gul - 16/Jun/08 01:55 AM
hi dan!!
Could u please explain me vat does following means?

var sendPoll = function() {
// Workaround IE6 bug where it caches the response
// Generate a unique query string with date and random
var now = new Date();
var data = 'timeout=' + timeout * 1000
+ '&d=' + now.getTime()
+ '&r=' + Math.random();

var options = { method: 'get', data: data, success: pollHandler, error: pollErrorHandler};
adapter.ajax(uri, options);
};
u'hv already set 25 sec that the long-polling socket will stay connected. does it mean u r going to set 25000 secs for timeout parameter which seems quite unrealistic.. iam confused..

by using ur file the following scenerio occurs:
1. ActiveMQ and tomcat running on my machine and if i disabled network connection from my machine the pooling doesnt break, js continously send request for message to MessageListenerServlet

2. but other machines running same application through my IP stop sending sending requests to servlet means polling breaks here, and on the establishment of network again js become able to send request to servlet and response also come back to activeMQ but pooling doesnt occur so that js fail to get response from servlet..

hope i explain the possible scenario.?

Thanks


Saira Gul - 16/Jun/08 03:50 AM - edited
hi dan!!
Could u please explain me vat does following means?
var sendPoll = function() {
// Workaround IE6 bug where it caches the response
// Generate a unique query string with date and random
var now = new Date();
var data = 'timeout=' + timeout * 1000
+ '&d=' + now.getTime()
+ '&r=' + Math.random();

var options = { method: 'get', data: data, success: pollHandler, error: pollErrorHandler};
adapter.ajax(uri, options);
};
u'hv already set 25 sec that the long-polling socket will stay connected. does it mean u r going to set 25000 secs for timeout parameter which seems quite unrealistic.. iam confused..

by using ur file the following scenerio occurs:
1. ActiveMQ and tomcat running on my machine and if i disabled network connection from my machine the pooling doesnt break, js continously send request for message to MessageListenerServlet

2. but other machines running same application through my IP stop sending sending requests to servlet means polling breaks here, and on the establishment of network again js become able to send request to servlet and response also come back to activeMQ but pooling doesnt occur so that js fail to get response from servlet..

hope i explain the possible scenario.?


Dan Schooler - 16/Jun/08 08:13 AM - edited
The timeout parameter takes milliseconds, so the multiplication by 1000 converts to seconds.
It is not 25000 seconds, but 25000 milliseconds, which is 25 seconds.
The other parameters ('d' and 'r') are just added to make the query string unique.
IE6 has a bug where it will not refetch the exact query it has seen before over GET and instead shows you the cached result (regardless of any no-cache directives from the server).

I'm not sure what your problem is.
Like I said, this has been working fine in my app for nearly 6 months.
You will need to debug your own unique scenario, I suggest using the firebug plugin, setting breakpoints in the scripts and seeing what is happening.

The only thing that comes to mind is that if you are actually terminating the Tomcat server, that is a very different thing than a client having intermittent connectivity. My solution is really just to handle the network cable getting unplugged or the wifi being flaky, it is not designed to handle a server restart.

When you restart the server, the session that your client had (and any topic subscriptions) are probably no longer valid, and so the client may need to make a new request for the topic..... maybe something like this:

//Un-Listen from topic
org.activemq.Amq.removeListener("yourTopic", "topic://Your.Topic");

//One second delay to wait for the Un-Listen to happen
//Then Re-Listen
setTimeout(function(){ org.activemq.Amq.addListener("yourTopic", "topic://Your.Topic", yourHandler); }, 1000);


Saira Gul - 16/Jul/08 12:12 AM
hi Dan!!

I have added your's modified amq.js files in my application, its work quite fine. Thanks.

I want to know one thing is there any impact of pooling on activeMQ performance? Actually ActiveMQ got disconnected after giving the following exception at console

"Could not accept connection : Channel was inactive for too long"

and also i got this exception in application log:

"Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused; nested exception is java.net.ConnectException: Connection refused"

I wonder due to pooling ActiveMQ becomes slower than Ajax client, is it true or my misconception?

Thanks