0

Asynchronous UI Update (web services)

asked 2014-09-05 23:26:31 +0800

carpolva gravatar image carpolva
155 4

updated 2014-09-05 23:27:47 +0800

Hi!.

Here are some details in a multi-user webapp that I'm building:

  1. The webapp is deployed in server AAA.

  2. An user executes something in the browser, then press a "send" button and some data is sent to another server (server BBB) through web service.

  3. Server BBB executes a process and sends an asynchronous response (callback) to the webapp through web service.

  4. When the callback is received in server AAA, some data need to be updated in the corresponding user screen.

I've read about Asynchronous UI Update using server push:

advanced-zk-asynchronous-ui-updates

advanced-zk-asynchronous-ui

But the provided examples use threads that are executed, I just need to update the corresponding user UI only when the webapp receives an asynchronous response from a web service.

Is there any way to achieve this?. I'm using ZK 6.5.1 version.

Any help will be appreciated, thanks!!

Best regards.

delete flag offensive retag edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2014-09-07 06:51:35 +0800

chillworld gravatar image chillworld flag of Belgium
5367 4 9
https://github.com/chillw...

updated 2014-09-09 08:04:35 +0800

You must ask yourself if server AAA wait for the response of server BBB.
Normally he does and your next line of code is when you have reach the answer.
I work also with webservices and you use it like a DB. (DB is normally also on server CCC).

Like I understand there are 2 possibility's.

First one :

You just call the webservice from your viewmodel through the service tier.
Now nothing is broken, and just do notifychanged.

Second one :

Put it in a thread if you need it to be in the background.
Nothing is wrong with creating a thread and then follow your links.

Edit :

Example how you could use thread and even notify the correct composer
It's not in ZK envirment but you found already the 2 links for threads so just implement that.

Composer.java :

/**
 *
 * @author chillworld
 */
public class Composer {

    private int number;

    public Composer(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }

    public void callManagerForData() {
        Thread t = new CallWebService() {
            @Override
            public void run() {
                System.out.println("add obeserver  " + getNumber());
                Manager.INSTANCE.callWebService(this);
            }
        };
        t.start();
    }

    public void refresh(String data) {
        System.out.println("Refresh done of composer " + number + " with data : '" + data + "'");
    }

    abstract class CallWebService extends Thread implements Observer {

        @Override
        public void update(Observable o, Object arg) {
            refresh((String)arg);
        }
    }
}

Manager.java:

/**
 *
 * @author chillworld
 */
public enum Manager {
    INSTANCE;

    private AnswerWebService service = new AnswerWebService();

    public void callWebService(Observer o) {
        service.addObserver(o);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
        }
        service.postAnswer();
    }
}

AnswerWebService.java:

/**
 *
 * @author cossaer.f
 */
public class AnswerWebService {

    private final List<Observer> observers = Collections.synchronizedList(new ArrayList<Observer>());

    public void postAnswer() {
        // handle data
        synchronized (observers) {
            if (observers.size() > 0) {
                Observer o = observers.remove(0);
                o.update(null, "mine data");
            }
        }
    }

    public boolean addObserver (Observer o) {
        return observers.add(o);
    }
}

TestObserverPattern.java:

/**
 *
 * @author chillworld
 */
public class TestObserverPattern {

    public static void main(String[] args) {
       List<Composer> composers = new ArrayList<Composer>();
       for (int i = 0; i<20;i++) {
           composers.add(new Composer(i));
       }
       Collections.shuffle(composers);
       for (Composer c : composers) {
           c.callManagerForData();
       }
    }
}

Hope this could be usefull in your case.

Take care, cause I don't know how you link the asyn call to the answer, I created this case to link first call => first answer.
This is normally open for bugs when call's come at close time rate.

Greetz chill.

link publish delete flag offensive edit

Comments

Hi chillworld, thanks for your response.

The matter is that in server AAA I don't wait for server BBB's response because it's an asynchronous call, so when the asynchronous callback is returned I must to keep some kind of reference to the corresponding user UI due to it's a multi-user webapp.

carpolva ( 2014-09-08 13:47:43 +0800 )edit

Maybe saving in somewhere (a hashmap can be) a relation between the user and his zk desktop?.

Best regards.

carpolva ( 2014-09-08 13:47:48 +0800 )edit

show me your asynctask class and your part of vm how you call it. I'll create your solution(asynctask is basicly a kind of thread)

chillworld ( 2014-09-08 14:06:31 +0800 )edit
0

answered 2014-09-08 18:42:21 +0800

carpolva gravatar image carpolva
155 4

Thanks chillworld, here's a simplified example:

My composer in AAA machine:

public class MyBean extends GenericForwardComposer{
     private Label myLabel1; //with getters and setters
     private Label myLabel2; //with getters and setters

     public void onClickSend(ForwardEvent event) {
          Data someData = processSomeData();

          /*calls the web service in BBB machine
            this is done through a singleton manager (spring bean)
            it's asynchronous so it doesn't wait for a response*/
          getSingletonManager().send(someData);
     }
}

Then, here is the callback class (in AAA machine) where the asynchronous response will be received from BBB server:

public class CallbackServiceImpl implements CallbackService {

     @POST
     @Consumes("application/json")
     @Path("/notifyProcess")
     @Override
     public void notifyProcess(ResultData someResultData) {
          /*Here I receive the asynchronous response, with the response data and I need
            to update the labels of the composer (myLabel1 and myLabel2) of the corresponding user
            who sent the previous request (think that other multiple users will be concurrently
            using the webapp)*/

         ???
     }
}

I see that components can be accessed only in event listeners, but I haven't figured yet how to do this for my particular case (yes, I know that documentation examples are very similar cases, just like you said "asynctask is basicly a kind of thread" jaja).

I'm using 6.5.1 ZK version, with MVC pattern (not MVVM).

Thanks for any help.

Best regards.

link publish delete flag offensive edit

Comments

oke I see your problem and have a possible solution in mine head (work it out later to real code) but now I have one more question, if user x do call and user y 0.2 seconds later => Always same data returned or is data user specific?

chillworld ( 2014-09-08 19:57:05 +0800 )edit

Hi chillworld.

Each data is user specific, even the same user will get different data on each request. I really appreciate your help, thanks.

carpolva ( 2014-09-08 20:24:34 +0800 )edit

there is some fundamently wrong with the application. You use a sort of webservioce to receive answers. Each user has differtent data => 2 users at same time click => who is the first that retrieve data? I can write the code but you will have bugs in it (like people see other data then requested)

chillworld ( 2014-09-09 05:40:30 +0800 )edit

or you must have somewhere a link from the manager to the answer or the webservice has to return something what can identify who need's the data.

chillworld ( 2014-09-09 05:42:38 +0800 )edit

Hi Chillworld.

Thanks, I'll adapt and test your solution and I'll let you know the results. Don't worry about multiple user data, I have a way to link and identify each user request.

Best regards.

carpolva ( 2014-09-09 22:15:26 +0800 )edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2014-09-05 23:26:31 +0800

Seen: 54 times

Last updated: Sep 09 '14

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More