-
1. Re: Seam Remoting und JMS Topic subscription questions.
shane.bryzak Oct 11, 2006 7:32 AM (in response to appendix)The code for dealing with stale subscriptions is a little messy at the moment. However to deal with your immediate issue, if you can somehow pass your subscription token to the next page (with a hidden field or something) then you can manually insert your subscription into the registry like this:
Seam.Remoting.subscriptionRegistry.push({topic:topicName, callback:callback, token:token});
Then simply call Seam.Remoting.poll() to kick off the polling process. -
2. Re: Seam Remoting und JMS Topic subscription questions.
appendix Oct 13, 2006 2:33 AM (in response to appendix)Hi, thanks for your reply!
I've tried to follow your hint, but somehow it seems that I cannot access the token after subscription to be able to write it to an input field.
The xhtml page is defined as following:<script type="text/javascript"> //<![CDATA[ Seam.Remoting.setDebug(true); function connect() { for (var i = 0; i < Seam.Remoting.subscriptionRegistry.length; i++){ Seam.Remoting.log(Seam.Remoting.subscriptionRegistry.topic); } Seam.Remoting.subscribe("taskListTopic", channelMessageCallback); } Seam.Remoting.setPollTimeout(10); Seam.Remoting.setPollInterval(3); connect(); function channelMessageCallback(message) { Seam.Remoting.log("msg.rcvd"); window.location.href=window.location.href; } // ]]> </script> <!-- /Seam Remoting --> <f:view> <h2><h:outputText value="#{msgs['home.Title']}" /></h2> <!-- here follows the view [.. snipped .. ] --> </f:view> <script type="text/javascript"> //<![CDATA[ Seam.Remoting.log("Script at the bottom of page..."); function fillTokenField(){ Seam.Remoting.log("filling input field with token"); var tokenField = document.getElementById('token'); tokenField.value="somethg"; Seam.Remoting.log(tokenField.value); for (var i = 0; i < Seam.Remoting.subscriptionRegistry.length; i++){ Seam.Remoting.log(i+": "+Seam.Remoting.subscriptionRegistry.topic+": "+Seam.Remoting.subscriptionRegistry.token); } tokenField.value = Seam.Remoting.subscriptionRegistry[0].token; Seam.Remoting.log(tokenField.value); } fillTokenField(); // ]]> </script>
After the page has been called, Seam log shows the following content:Fri Oct 13 2006 08:09:54 GMT+0200: Request packet: <envelope><body><subscribe topic="taskListTopic"/></body></envelope> Fri Oct 13 2006 08:09:54 GMT+0200: Script at the bottom of page... Fri Oct 13 2006 08:09:54 GMT+0200: filling input field with token Fri Oct 13 2006 08:09:54 GMT+0200: somethg Fri Oct 13 2006 08:09:54 GMT+0200: 0: taskListTopic: undefined Fri Oct 13 2006 08:09:54 GMT+0200: undefined Fri Oct 13 2006 08:09:54 GMT+0200: Response packet: <envelope><body><subscription topic="taskListTopic" token="ba340565-eeba-483f-9d10-9171e8fac57d"/></body></envelope> Fri Oct 13 2006 08:09:54 GMT+0200: Request packet: <envelope><body><poll token="ba340565-eeba-483f-9d10-9171e8fac57d" timeout="10"/></body></envelope>
The last two lines of the log are the first polling performed. But as seen, at the point where the subscription list is written to the log, the token for the current subscription is 'undefined'.
When is the token initialized?
Am I missing something obvious?
And just to make sure, I got you right, after I've written the token to an input field, I need to make sure this token is pushed into the subscriptionRegistry again after the page has reloaded.
After that I start the polling process with Seam.Remoting.poll(), right?
Thank you again,
Kurt -
3. Re: Seam Remoting und JMS Topic subscription questions.
shane.bryzak Oct 13, 2006 6:24 AM (in response to appendix)The token is passed back in the response to the subscribe request, and added to the subscription registry in Seam.Remoting.subscriptionCallback(). You should put the code for setting the token in your channelMessageCallback() method (only setting it if it hasn't already been set).
-
4. Re: Seam Remoting und JMS Topic subscription questions.
appendix Oct 16, 2006 3:28 AM (in response to appendix)Hi, thanks for helping me on this topic!
But I'm not sure, if your suggestion would realy help me out, because the channelMessageCallback() method is not always called _before_ the page is refreshed. Actually in my scenario it is never called before the first refresh.
Imagine this timeline:
1) The page is rendered and the subscription takes place
2) The user hits a button on the page triggering some action method
3) The page is re-rendered because of the action triggered in 2)
4) A JMS message is published on the topic ....
At point 3) a new subscription would have taken place ....
But I've noticed this Monday morning, that the exact same code produced a valid subscription AND token in the script at the bottom of the page [see code of posting Fri Oct 13, 2006 02:33 AM](after subscription).
So I thought about a racing condition. After calling Seam.Remoting.subscribe() at the top of the page, your code is generating the token and is putting it into the SubscriptionRegistry. Simultaneously the page is rendered and the script at the bottom of the page is executed. If the token ends up in the registry before that point, everythings fine. But most of the times it won't!
I think I've confirmed the issue by delaying the script at the bottom of the page artificially.setTimeout('fillTokenField();', 1000);
I'm not sure, if this is the best approach. Assumptions on "how long something usually takes" have a tendency to break code after a while. Is there another way of knowing, if the subscription is completely performed, hence the token is generated?
Thank you again for sticking with me,
Kurt -
5. Re: Seam Remoting und JMS Topic subscription questions.
shane.bryzak Oct 16, 2006 6:57 AM (in response to appendix)Seam.Remoting.subscribe() sends an asynchronous request to the server, which means you're not guaranteed to have a token in the subscription registry by the time your page gets to the script at the bottom of the page.
I suggested putting the code to set the token inside your callback method, because it is synchronous with the subscription request. However if your callback method isn't being called before the page is refreshed (because you haven't received any messages during that time) then you can override SeamRemote.subscriptionCallback() instead:<script type="text/javascript"> var cb = SeamRemote.subscriptionCallback; SeamRemote.subscriptionCallback = function(doc) { cb(doc); document.getElementById('token').value = Seam.Remoting.subscriptionRegistry[0].token; } </script> }
Using setTimeout() is definitely not the way to do it. -
6. Re: Seam Remoting und JMS Topic subscription questions.
appendix Oct 17, 2006 11:16 AM (in response to appendix)Thanks Shane,
overriding the subscriptionCallback definitely did the trick. I never wanted to use the setTimeout() version in a production environment.
So finally I got the token in an input field and this is passed along the request until the page is rerenderd.
I followed your suggestion, pushed the token manually into the registry and after calling Seam.Remoting.poll() the polling starts with the same token!
But ;), the polling stops after the first (polling-)request times out because of an JavaScript ErrorSeam.Remoting.loadingMsgDiv has no properties
.
It seems uthat there is more going on behind the scenes at subscription.
Sorry to bother you again, bt do you have any thoughts on that one?
Kurt -
7. Re: Seam Remoting und JMS Topic subscription questions.
shane.bryzak Oct 17, 2006 6:02 PM (in response to appendix)Hmm, I'm not sure why you'd be getting that specific Javascript error in relation to messaging. The only place I can see it possibly happening is in the Seam.Remoting.hideLoadingMessage() method - just to be safe I've updated this method in CVS to check that Seam.Remoting.loadingMsgDiv is not null, so you might like to get the latest version from CVS and try that.
Alternatively, you can just add this code snippet to your page if you don't want to get the latest CVS version:Seam.Remoting.hideLoadingMessage = function() { if (Seam.Remoting.loadingMsgDiv) Seam.Remoting.loadingMsgDiv.style.visibility = 'hidden'; }
-
8. Re: Seam Remoting und JMS Topic subscription questions.
appendix Oct 18, 2006 3:02 AM (in response to appendix)Hi,
that finally did the trick! Thank you again for your help.
By the way, I'm using JBossMessaging instead of JBossMQ and therefore needed to set the connection provider in the subscriptionRegistry.
Is there a reason why the property connectionProvider in org.jboss.seam.remoting.messaging.SubscriptionRegistry lacks a getter method and hence cannot be set by a parameter in seam.properties, components.xml or web.xml?
I know, it's only the the getter missing, but without that java.beans.PropertyDescriptor won't extract the bean interface properly and the property cannot be set in org.jboss.seam.Component.
I needed to set the connection provider since the default one only uses the hardcoded JDNI_Factory_Name "UIL2ConnectionFactory".
Regards, Kurt -
9. Re: Seam Remoting und JMS Topic subscription questions.
shane.bryzak Oct 18, 2006 3:15 AM (in response to appendix)"appendix" wrote:
Is there a reason why the property connectionProvider in org.jboss.seam.remoting.messaging.SubscriptionRegistry lacks a getter method and hence cannot be set by a parameter in seam.properties, components.xml or web.xml?
I'll add the getter method for you today. -
10. Re: Seam Remoting und JMS Topic subscription questions.
appendix Oct 19, 2006 2:09 AM (in response to appendix)Thank you Shane, you've been really helpful!
The getter is not an immediate issue for me. I just wanted to point that out, that some other guy later on won't need to worry, why the provider cannot be set in components.xml :)
Again, I'd like to thank you for your great help!
Kurt