Stream in servlet object causing problems

P

paulfugl

Please help with this!

I am developing a webapplication (running on Tomcat) where a servlet in
its doGet() method opens a socket and
sends that socket's inputstream to the browser. Do I need to inplement the
serlvet as a thread, i.e. a new thread is created
every time someone triggers the doGet() method, or is this sorted out by
the servlet container itself?

My problem is that when I open a new browser window and execute that
servlet again, my app seems to lose track of where
to send the data, so the data is sent to the new browser window only. I am
using the "pushlet" concept to create a continously
stream of data to the browser.

In brief, my servlet doGet() method looks like this:

public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException {
try {
oStream = new PrintWriter(response.getOutputStream());
cSocket = new Socket("127.0.0.1", 3726);
iStream = new BufferedReader(new
InputStreamReader(cSocket.getInputStream()));
while(true) {
String line = inputStream.readLine();
oStream.println(jScriptStart + " printMsg('" +
line + "');" + jScriptEnd);
oStream.flush();
}
} catch (IOException e) {
oStream.println(jScriptStart + " printMsg('" + e + "');" +
jScriptEnd);
oStream.flush();
}
}

I suspect that the compiled object is simply re-used when I make another
request, which might explain a little bit but
I have tried to make the servlet as a thread (implementing Runnable) but
same problem appeared.

Cheers,
Paul
 
A

Anton Spaans

Please help with this!

I am developing a webapplication (running on Tomcat) where a servlet in
its doGet() method opens a socket and
sends that socket's inputstream to the browser. Do I need to inplement the
serlvet as a thread, i.e. a new thread is created
every time someone triggers the doGet() method, or is this sorted out by
the servlet container itself?

My problem is that when I open a new browser window and execute that
servlet again, my app seems to lose track of where
to send the data, so the data is sent to the new browser window only. I am
using the "pushlet" concept to create a continously
stream of data to the browser.

In brief, my servlet doGet() method looks like this:

public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException {
try {
oStream = new PrintWriter(response.getOutputStream());
cSocket = new Socket("127.0.0.1", 3726);
iStream = new BufferedReader(new
InputStreamReader(cSocket.getInputStream()));
while(true) {
String line = inputStream.readLine();
oStream.println(jScriptStart + " printMsg('" +
line + "');" + jScriptEnd);
oStream.flush();
}
} catch (IOException e) {
oStream.println(jScriptStart + " printMsg('" + e + "');" +
jScriptEnd);
oStream.flush();
}
}

I suspect that the compiled object is simply re-used when I make another
request, which might explain a little bit but
I have tried to make the servlet as a thread (implementing Runnable) but
same problem appeared.

Cheers,
Paul

This is from the JavaDoc's HttpServlet:
=============================
Servlets typically run on multithreaded servers, so be aware that a servlet
must handle concurrent requests and be careful to synchronize access to
shared resources. Shared resources include in-memory data such as instance
or class variables and external objects such as files, database connections,
and network connections. See the Java Tutorial on Multithreaded Programming
for more information on handling multiple threads in a Java program.

=============================

The doGet() can be called at the same time by multiple threads. Each
incoming request is serviced by a thread from a thread-pool maintained by
the webserver. This means that in general the doGet() does not necessarily
get serviced by the same thread. Do not make your Servlet Runnable!

The 'while(true)' in your doGet() is the culprit. Every request that is
handled by your servlet never ends. This is generally not a good thing to
do. The browser may want to timeout (suppose your input-socket is not
sending data for a while) and may close the connection (=target of the
repsonse.getOutputStream()).

Also, when sending a page that behaves like a 'server-push' (instead of the
more common client-pull), you have to format your http-response in a certain
way so that the browser can handle it properly (i.e. not timing out,
displaying partial results/progress-indicator, etc). Your document has to be
of content-type 'multipart'. See below link for some more info:

http://wp.netscape.com/assist/net_sites/pushpull.html

Good luck.
 
P

Paul

This is from the JavaDoc's HttpServlet:
=============================
Servlets typically run on multithreaded servers, so be aware that a
servlet
must handle concurrent requests and be careful to synchronize access to
shared resources. Shared resources include in-memory data such as
instance
or class variables and external objects such as files, database
connections,
and network connections. See the Java Tutorial on Multithreaded
Programming
for more information on handling multiple threads in a Java program.

=============================

The doGet() can be called at the same time by multiple threads. Each
incoming request is serviced by a thread from a thread-pool maintained by
the webserver. This means that in general the doGet() does not
necessarilyget serviced by the same thread. Do not make your Servlet
Runnable!

The 'while(true)' in your doGet() is the culprit. Every request that is
handled by your servlet never ends. This is generally not a good thing to
do. The browser may want to timeout (suppose your input-socket is not
sending data for a while) and may close the connection (=target of the
repsonse.getOutputStream()).

Also, when sending a page that behaves like a 'server-push' (instead of
the more common client-pull), you have to format your http-response in a
certain way so that the browser can handle it properly (i.e. not timing
out,
displaying partial results/progress-indicator, etc). Your document has to
be of content-type 'multipart'. See below link for some more info:

http://wp.netscape.com/assist/net_sites/pushpull.html

Good luck.

Thanks for your reply Anton. I am not sure if I understand what
you mean with the doGet() not necessarily get services by the same
thread though..guess I need to read some more documentation? :)

Anyways, regarding my while(true) being the culprit, I actually don't
want the requests handled by my servlet to end. I guess I need to
make sure the browser does not time out but except that I can't see
why this shouldn't work, even if the socket does not send any data
for a while. The while(true) is rather meant to keep the connection
alive and feed the browser with dynamic data. I could have used an
applet, but wanted to see if I could manage without that, and rather
use JavaScript and DHTML to update the web page with the data sent
from by the servlet. (OK, bad trick, but I use a popup with hidden
frames so that the user does not see what's going on). (And THAT part
works..the thing that does not work is to send data to all browser
windows, not only the last one that made a request)
 
A

Anton Spaans

Comments are within your original message:

Paul said:
Thanks for your reply Anton. I am not sure if I understand what
you mean with the doGet() not necessarily get services by the same
thread though..guess I need to read some more documentation? :)

The doGet() method can be called by multiple threads.
1. Webserver gets request from browser.
2. Webserver routes this request to your servlet (web.xml mapping)
3. Webserver obtains an idle thread from its thread pool (or creates a new
one)
4. This (new) thread will run the doGet() method.

This means that doGet() can be run in multiple threads at the same time....
Luckily, because your doGet() never ends!
Anyways, regarding my while(true) being the culprit, I actually don't
want the requests handled by my servlet to end.

It is not good that your doGet() never ends. Suppose 1000 http-requests are
issued. This means your webserver will need to create 1000 threads to run
your doGet(), because your doGet() never ends (i.e. any thread running your
doGet() will never end and will never be idle again). So, every new request
will cause your webserver to create a new thread. Your webserver will run
out of resources pretty soon.
I guess I need to
make sure the browser does not time out but except that I can't see
why this shouldn't work, even if the socket does not send any data
for a while. The while(true) is rather meant to keep the connection
alive and feed the browser with dynamic data.

Again, look at http://wp.netscape.com/assist/net_sites/pushpull.html for
properly formatting the server-pull method.
I could have used an
applet, but wanted to see if I could manage without that, and rather
use JavaScript and DHTML to update the web page with the data sent
from by the servlet. (OK, bad trick, but I use a popup with hidden
frames so that the user does not see what's going on). (And THAT part
works..the thing that does not work is to send data to all browser
windows, not only the last one that made a request)

-- Anton.
 
P

Paul

Comments are within your original message:



The doGet() method can be called by multiple threads.
1. Webserver gets request from browser.
2. Webserver routes this request to your servlet (web.xml mapping)
3. Webserver obtains an idle thread from its thread pool (or creates a
new
one)
4. This (new) thread will run the doGet() method.

This means that doGet() can be run in multiple threads at the same
time....
Luckily, because your doGet() never ends!


It is not good that your doGet() never ends. Suppose 1000 http-requests
are issued. This means your webserver will need to create 1000 threadsto
run your doGet(), because your doGet() never ends (i.e. any thread
running your doGet() will never end and will never be idle again). So,
every new request will cause your webserver to create a new thread.Your
webserver will run out of resources pretty soon.

Actually, I did not mean "never ending" literally, i.e. the threads being
there forever. That would certainly suck the webserver's resources pretty
quickly, I agree on that. As soon as the client quits (closes the window
or quits manually) an exception will occur and the thread dies. Also the
number of concurrent clients (threads) will be limited and will never reach
a 1000 or so (say 30 at max). Still no good idea?

How would you do this? I want to have the browser window dynamically
updated with data without utilizing applets..somehow..
 

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

Forum statistics

Threads
474,470
Messages
2,571,807
Members
48,797
Latest member
PeterSimpson
Top