Fetching an URL from a GUI, repeatedly and asynchronously

A

Alexander Farber

Hello,

I have a probably simple question, but lack Java experience myself.

I'm programming a multi-player card game applet, talking to
an Apache module. (http://preferans.de , is in Russian though).

My problem is: if I will call something like

url = new URL("http", getCodeBase().getHost(),
"/my_module" + some_changing_params);
conn = (HttpURLConnection) url.openConnection();
BufferedReader input = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
process_response_and_update_GUI(line);
}
input.close();

from the actionPerformed(), then my applet will keep freezing.

So I need a separate Thread.

But what exactly should I do in that separate Thread?
Keep polling an "url" variable, and once it's not null (set by
the actionPerformed()) run the code above, then update
GUI and set "url" back to null?

I think polling is not the best way. If I do it constantly, then
my applet will eat CPU. And if I add a Thread.sleep(5000)
inbetween to save some CPU, then the GUI will be not so
responsive (it isn't already because of the HTTP stuff)

Any suggestions please?

Regards
Alex
 
A

A. Farber

Hi Bruce,

thank you, but I actually am looking for something
other than TimerTask.

I need something like C-functions poll() or select(),
which would sleep and wake up when an event happens
(for example a variable "url" modified from another thread)

Regards
Alex
 
M

Mitch

Java has something called Condition
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Condition.html
which i found very helpful in my current project.

You basically have a condition (in the normal sense) which you test for
and then if fails (IE you dont want to continue yet) you call
conditionReference.await()

A method which i use is below (ignore the locks for now, but you will
need them if you use this method)

Code:
public void waitForSignalChange()
{
signalLock.lock();
redSignal.awaitUninterruptibly();
signalLock.unlock();
}

( awaitUninterruptibly() is similar to await() )

This is called when my signal is RED and my train (Rail simulation) has
to wait. It puts the thread to sleep until a signalAll() method is
called as in below

Code:
public void signalAll()
{
signalLock.lock();
redSignal.signalAll();
signalLock.unlock();
}

Once something in my program changes the signal (from red to green for
example) the signal all method is called and the thread that is
currently under the await() method will recieve a signal and can
continue.

so in your case when your thread is waiting for the url value it can be
sleeping with the await method and then whatever your code is to set
the url you can set the url and call signallAll immeadiately afterwards
which would alert the previous thread that the url has been set.

Let me know if that helps at all!

Mitch.
 
O

opalpa

Preference brings a couple of memories back from high school.

A russian classmate taught me and the game is enjoyable. Make an
american interface, please.

Now to your problem: How come the URL will be null to begin with? Is
the server frequently making URLs for one game? I don't quite
understand " Keep polling an url variable, and once it's not null ".

If you are having server make URLs frequently during a game then
perhaps the URLs should already exist and server will delay providing
info until it is ready. That way the wait will be in the first call to
readLine().



All the best,
Opalinski
(e-mail address removed)
http://www.geocities.com/opalpaweb/
 
A

A. Farber

Thanks, I'll add an English interface for the game later :)
(for the website itself you can already select
English, German or Russian once you register there).

The URL I call from the applet is changing constantly,
because I send GET requests to my Apache module.
And I have to use GET, because then I can use
If-Modified-Since (conditional GETs) to save some
bandwith and speed the things up.

I've read http://java.sun.com/docs/books/tutorial/essential/threads/
(thanks James, that was a good advice) and am using wait/notify now:


URL url, alive;

public void init() {
alive = new URL("http", getCodeBase().getHost(),
"/my_module?user=" + user + "&pass=" + pass +
"&event=alive");
new Thread(this).start();
}

// set the url to be fetched by the getData()
synchronized void setUrl(String event, String args) {
while (url != null) {
// wait for getData() to clear the url
wait();
url = new URL("http", getCodeBase().getHost(),
"/my_module?user=" + user + "&pass=" + pass +
"&event=" + event + "&args=" + args);
// wake up the getData()
notify();
}
}

// fetch either the url set by the setUrl(), or the alive URL
synchronized void getData() {
HttpURLConnection conn;

// wait for setUrl() or timeout in milliseconds
wait(30 * 1000);
if (url != null)
conn = (HttpURLConnection) url.openConnection();
// timeout
else
conn = (HttpURLConnection) alive.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("If-Modified-Since", modified);
//conn.setUseCaches(true);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader input = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
area.append(line + NL);
}
input.close();
// wake up setUrl()
url = null;
notify();
}
}

public void run() {
while (true)
getData();
}

(I've removed the try/catches above).

If you have a better suggestion, please let me know.

The wait/notify/threads are difficult,
I'm still not sure if I got it right

Regards
Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top