Announcement Announcement Module
Collapse
No announcement yet.
Timeout - Best practice? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Timeout - Best practice?

    Hi,

    In my application I use Flex, BlazeDS, Spring, Spring Security and Spring BlazeDS integration.

    My problem is that I am not sure how to handle timeouts correctly. I was hoping that I could set up a listener on the server which triggers on session timeout and then sends a notification to the client. I tried to implement this by creating a custom Adapter which extends ServiceAdapter and implements FlexSessionListener.
    Code:
    	public void sessionCreated(FlexSession session) {
    		session.addSessionDestroyedListener(this);	
    	}
    
    	public void sessionDestroyed(FlexSession session) {
    		//MessageService msgService = (MessageService) getDestination().getService();
    		MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
    	...
    	}
    
    @Override
    	public Object invoke(Message message) {...}
    I hoped that this class would trigger the sessionCreated method when logging in, and the sessionDestroyed method when loggin out (and timeout).
    And so it does when I register it as a listener in Web.xml .The problem then is that MessageBroker.getMessageBroker(null) returns null. (And the invoke method never runs).
    I should probably define this in the application-context like this:
    Code:
    <flex:remoting-destination ref="testPush" channels="my-streaming-amf" service-adapter="TestAdapter"/>
    and this to the messaging-service.xml file:
    Code:
    <adapters>
            <adapter-definition id="TestAdapter" class="package.TestListener"/>
        </adapters>
    But now I get this error message: No adapter with id 'TestAdapter' is registered with the service 'remoting-service'.
    Can someone please tell me why? What am I doing wrong?



    And a second question:
    Is the following correct: To be able to push the timeout notification (in sessionDestroyed) to the client I have to set up a new Channel like this:
    Code:
    <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
    And then use Producer and Consumer on the client side to handle the timeout notification.(So far I have only used RemoteObjects)

    I'm new to blazeDS so I would be delighted to get some opinions on how to best handle session timeouts.

  • #2
    Seriously, there must be someone with a qualified answer in here! I would appricate some help.

    Comment


    • #3
      Originally posted by 2rr View Post
      The problem then is that MessageBroker.getMessageBroker(null) returns null. (And the invoke method never runs).
      Why not just use Spring to inject the MessageBroker into your listener? Something like:

      Code:
      <bean id="myListener" class="com.foo.MyListener">
          <property name="messageBroker" ref="_messageBroker" />
      </bean>
      or even:

      Code:
      @Component
      public class MyListener implements FlexSessionListener {
      
          private MessageBroker messageBroker;
      
          @Autowired
          public void setMessageBroker(MessageBroker broker) {
              this.messageBroker = broker;
          }
      
          ...
      }
      Let's take a step back for a minute before I try to answer this further. What behavior exactly are you trying to achieve? Just notify the user when their session is timed out? I think I'm confused by the fact that you're trying to use an Adapter for this.

      Comment


      • #4
        First of all, I really appreciate your answer. Thank you!

        The use of an Adapter confused me to. The reason I used it was because I followed an example found on the web. But in that example they needed to get an initial state from a variable at the server. Hence they uses a producer on the client which invoked the adapter's invoke method.

        Back to the use of MessageBroker.getMessageBroker(null). I found out that I could use FlexContext.getMessageBroker(). If you recommend using your approach, why?

        What I want: Simply to push a message to the client when his session has expired. I also need to store a Map of all user sessions, which I can use to determine if the maximum user limit is reached. Essentially this is what I hope to do:

        Code:
        public class MyListener implements FlexSessionListener {
        	
        	public MyListener() {
        		FlexSession.addSessionCreatedListener(this);
        	}
        	
        	public void sessionCreated(FlexSession session) {
        		session.addSessionDestroyedListener(this);	
        		
        		//Check against session map, if max limit reached, notify user using the MessageBroker.
        	}
        	
        	public void sessionDestroyed(FlexSession session) {
        		MessageBroker msgBroker = FlexContext.getMessageBroker();
        		
        		//Session destroyed, notify user using the MessageBroker.
        	}
        }
        Up until now I have only used one channel definition:
        Code:
        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
        and RemoteObjects to communicate.

        I guess that I have to define a new channel
        Code:
        <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
        to be able to push messages to the client? And on the client set up a Consumer which subscribes to the correct destination?

        Right now I'm stuck on this error message: 'The 'Remoting' service can only process messages of type 'RemotingMessage''. I guess I'm trying to use the default channel to push messages to the client, and that is not possible?

        I've seen that some people handles the timeout on the client. When the timeout happens they send a notification to the server, which invalidates the session. What is most common (and most safe), timeout on client or on server?

        Comment


        • #5
          If you want to alert the client when the session has expired, you have to configure a Messaging Service on the server side and a consumer on the client side.
          Have a look here :
          http://livedocs.adobe.com/blazeds/1/..._1.html#171137
          and
          http://static.springsource.org/sprin...html/ch05.html

          What do you mean by
          I've seen that some people handles the timeout on the client.
          Using a timer on the client side set to 20 minutes for example ? In that case, what if the server session expire before ?

          Comment


          • #6
            First off, +1 to the post above. You can do this pretty simply through the MessagingService support that Spring BlazeDS Integration provides. In this case, I'd suggest utilizing the MessageTemplate to push the notification to the client from your listener. Check out the "simplepush" and "traderdesktop" samples along with their corresponding SimpleFeed and MarketFeed java classes in the Test Drive.

            Originally posted by 2rr View Post
            Back to the use of MessageBroker.getMessageBroker(null). I found out that I could use FlexContext.getMessageBroker(). If you recommend using your approach, why?
            Well, you're somewhat asking why you should use dependency injection, and that's a pretty broad topic. I generally think relying on a static locator like this in your code is a bad idea when it is so easily avoidable. Injecting the MessageBroker will make your code a bit easier to unit test. Sadly, the MessageBroker is not an easy object to mock, but you can use the framework classes provided by Spring BlazeDS Integration to set one up with just what you need for your test.

            Comment

            Working...
            X