12 Replies Latest reply on Feb 25, 2008 7:57 AM by bobbiee

    Push Push Push

    bobbiee

      I am tired of making that push component works, I saw some examples in this forum and people seemed happy to run it at least in IE, but I am having troubles in every browser (even after I upgrade to 3.1.4). What am I doing wrong here?

      SomeBean
      ------------------
      private PushEventListener listener = new MyPushEventListener();
      
      public void addListener(Event listener listener) {
       synchronized (listener) {
       if (this.listener != listener) {
       this.listener = (PushEventListener) listener;
       }
       }
      }
      
      public void push () {
       synchronized (this.listener) {
       this.listener.onEvent(new EventObject(this))
       }
      }
      


      There is of course class MyPushEventListener implements PushEventListener with method onEvent, where is placed the code, which should be processed when the push method is being called. After listener is registered and some component on the page fires push method, there is never called the method from MyPushEventListener class onEvent, so there is no update at all. I wonder why, where is the mistake, as other people were able to run it successfully and I did exactly, what they have in their examples.

      Could somebody, who was able to make it works, give me a helping hand? Will be very happy to see it works here.

      Lukas

        • 1. Re: Push Push Push

          Hmm...we are working successfully with a4j:push in FF 2, IE 6 and IE 7...in Opera are problems. For which browsers you wanna get it work?

          Nothing seems to be wrong in your code...we are doing not much more than published in the developer guide.

          Try to find a simple example working in ONE browser, post it here and write, in which browsers it is NOT working. Then we can create a JIRA issue .

          • 2. Re: Push Push Push
            bobbiee

            Hi, thanks for reply,


            I was trying to make it work whole yesterday and I give up now. I tested it in mozila 2.0.11 and also in IE, the results were the same. I will probably have to use poll :(, which is not the right solution here. But anyway,I havent seen that anybody post the same problem as me, there are may things about that they see error or exception, I dont see anything, everything is fine, except I cant see that method MyPushEventListener.onEvent... is called. And this is pretty important, cause this is the way how to update pages on every clients, and thats push are for, right?

            • 3. Re: Push Push Push

              Okay, will try to help you with code. What works for us:

              page code (outside of every other form in the page):

              <a4j:form>
               <a4j:region>
               <a4j:push eventProducer="#{ctrl.addCommandListener}" interval="3000"
               data="#{ctrl.commandResult}" ajaxSingle="true"
               oncomplete="mediateCommandResult(data);" reRender="TreeNavigation" />
               </a4j:region>
              </a4j:form>
              


              And bean code:

               private PushEventListener commandEventListener;
              
               public void addCommandListener(EventListener listener)
               {
               synchronized (listener)
               {
               if (commandEventListener != listener)
               {
               commandEventListener = (PushEventListener) listener;
               }
               }
               }
              
               public void push(/* put here individual parameters*/)
               {
               //put here individual code
               synchronized (commandEventListener)
               {
               commandEventListener.onEvent(new EventObject(this));
               }
               }
              


              With calling the push method the push is executed when the next 3 seconds cycle is over - so the method specified in data attribute is called and the oncomplete method is executed.

              So you see I don't need any own PushEventListener. It is overwritten by the add-Method anyway. I posted a question about that some time ago but nobody from the team answers.

              Here the question again: How to get an own PushEventListener working??

              • 4. Re: Push Push Push
                bobbiee

                thanks man!

                but...as solutions differs from case to case, I have to ask you about data attribute inside the push and method oncompete. What is this commandResult property inside your bean? What does it contain? and is this mediateCommandResult method already written in rich api? Or I have to create that by myself? If I have to, I would like to ask you, how can I write it? I am not expert on javascript :(

                So far thanks for trying to help me.

                Lukas

                • 5. Re: Push Push Push

                  Hmm...I need to know, what exactly do you want to do with a4j:push to help you fast.

                  What we do (in this case): We have a graphical editor based on openJacob draw2D (http://draw2d.org/draw2d/). When the user is doing something here (create, delete, resize, move, connect and so on) we send an AJAX request with a4j:jsFunction to the bean to execute the concerning command (we use the command design pattern here). This command sends the information via RMI to an application server which does the real business logic, DB accessing and so on.

                  The answer to the client comes ASYNCHRONOUSLY. So here we need a4j:push. The following happened:

                  1.) The app server calls (again via RMI) the push method. With "individual code" I wanna say, here we place the command result and so on.

                  2.) A getCommandResult is called and a JSON-String is transferred to the web client for the javascript graphical editor.

                  3.) The mediateCommandResult is an own method again, that decides depending from commandResult, what the editor has to do.

                  BUT WHEN YOU DON'T HAVE SUCH A BIG SETTING FORGET IT ALL. You can use a4j:push much easier. Let's assume you wanna update a table from server side here the way:

                   public void push(/* put here code for new row*/)
                   {
                   //add the row data to the list that is backing your table
                   synchronized (commandEventListener)
                   {
                   commandEventListener.onEvent(new EventObject(this));
                   }
                   }
                  


                  Call this method from server side.

                  And here your a4j:push component

                  <a4j:form>
                   <a4j:region>
                   <a4j:push eventProducer="#{ctrl.addCommandListener}" interval="3000"
                   reRender="TheIdOfYourTable" />
                   </a4j:region>
                  </a4j:form>
                  


                  The following problems remain:
                  - what about other browsers than IE and FF?
                  - what about own listener?

                  • 6. Re: Push Push Push
                    bobbiee

                    OK, I have to explain beter:

                    I really want to use this push in the simplest way, as it can be, I have service tree (rich:tree) navigation. I create it dynamically from the bean. What I basically want is, when somebody create new service, he will see result after saving as a new item in the tree. This is OK. But I want other people whose are online at the time to see that change too without clicking any update button (as it works now with facelets in my application). I think push is the best solution - everybody who run the page, they register listener on server. I want, if somebody creates something which will affect the navigation tree, to let know every clients, that this change happen and want their navigation tree to be refreshed automatically.

                    As i said, i can see that listener is registered, I can see that if I click save button and save new service, there is

                    commandEventListener.onEvent(new EventObject(this));
                    this method called, but I also have to perform some method to reload the tree in the bean. I called that in MyPushEventListener.onEvent method, but this method is never called.

                    So, without using my own PushEventListener class, where should I put this method?

                    • 7. Re: Push Push Push

                      You need no extra method for reRendering your tree. Please use reRender-Method of a4j:push.

                      For your context you can exactly act like in my "reRender table" example with one add-on: you need a shared bean with application scope where you put the data for your tree and some logic to inform every session of data change.

                      1.) A user change the tree.

                      2.) His session bean informs the app bean of this change.

                      3.) The app bean update his data.

                      4.) The app bean informs every session of the change by calling their push methods.

                      Any more questions? :-)

                      • 8. Re: Push Push Push
                        bobbiee

                        I have to call "extra" method in backend to refresh my tree with new item.

                        1. new item is created
                        2. I need to refresh tree with thihis new item ()
                        3. then I can rerender my tree area and I will see changes

                        If I dont use refresh tree method, I will refresh tree area with the same values from backend. I am creating the tree dynamically, according to the data from dbs. right?

                        Or are u trying to say that I can put this refresh method inside the push method and other listeners will be somehow informed.....I think you reallt try to learn me some techics to do that, but so far my brain doesnt get it....your 1-4 points are logical, but how can I do it in my app? I have application scope bean with tree data, but how will I inform every session of data change??

                        • 9. Re: Push Push Push

                          Okay I try to make a few points clearer:

                          A)
                          We have to distinguish the "data update" from the "tree reRendering", there you are right.
                          First task is released by action method of a button (or something like this) when you change the tree data. This action method has to do step 2 of my previous explanation.
                          Second task is down at last by the reRender-Attribute of a4j:push.

                          B)
                          How to inform every session of data change? Don't know if it is the "professional" way. I do it like this:

                          1.) When a new user is logging in, and the session is created, the constructor of your session bean is called.

                          2.) Here you get your current sessionId from faces context and register this session in a map (sessionId/sessionBean object) in your application bean.

                          3.) On logout/invalidate session, you unregister your session the same way. Of course you have here the typical web app problem of "what if the user doesn't logout but simply close browser window?". Can't solve that here.

                          4.) When you now inform your application bean of a data change, it has a list of the current active sessions and references to the session beans. Iterate through it and call all their push methods.

                          • 10. Re: Push Push Push
                            bobbiee

                            OK, I think I understand u there. I though that push will do all this work instead of registering users sessions and remember them. I though push is only about to register listener, create onEvent action, inside where you put "refresh" code of whatever and every other clients get to know that something has changed and the refresh (and rerender) action is performed in all browsers which are connected to the server.

                            Your solution might work, but its little bit difficult and as you said, there is problem with logout. I give up with push and let poll do that job, however this is not right solution, but better little bit not right solution, than no solution at all:)

                            Thanks for helping me man. By the way, do you know about any color picker component? I made something in js before, but when I add richfaces into my project, it just somehow is not working. Was thinking to use richfaces colorpicker (paint2D I mean), but seems little bit difficult for users to pick their favourite color...

                            Anyway thanks a lot:)

                            • 11. Re: Push Push Push

                              It's great that we are talking about that! Put the listener directly in the app bean and having ONE listener telling it all clients would be much better than my session map. Will try that tomorrow.

                              Color picker component? I was searching for it, too. Please vote for it in the Richfaces Future List in the wiki!
                              I advised somebody in my team to develop an own color picker with some html and javascript. That is ready now and I'll try to integrate that in a modal panel and make it ajax-enabled with the help of RF.

                              May be I can publish it in the cookbook next time...we'll see.

                              • 12. Re: Push Push Push
                                bobbiee

                                good:) That color picker will be very useful for me, tried to use trinidad's picker, but I am not able to make tr works with myfaces, I always get render error. Hell!!!

                                Are you one of the guys whose develop richfaces?