views:

42

answers:

3

Hi all,

I'm interested in adding an HTML/web-browser based "log window" to my net-enabled device. Specifically, my device has a customized web server and an event log, and I'd like to be able to leave a web browser window open to e.g. http://my.devices.ip.address/system_log and have events show up as text in the web browser window as they happen. People could then use this as a quick way to monitor what the system is doing, without needing run any special software.

My question is, what is the best way to implement this? I've tried the obvious approach -- just have my device's embedded web server hold the HTTP/TCP connection open indefinitely, and write the necessary text to the TCP socket when an event occurs -- but the problem with that is that most web browsers (e.g. Safari) don't display the web page until the server has closed the TCP connection has been closed, and so the result is that the log data never appears in the web browser, it just acts as if the page is taking forever to load.

Is there some trick to make this work? I could implement it as a Java applet, but I'd much prefer something more lightweight/simple, either using only HTML or possibly HTML+JavaScript. Also I'd like to avoid having the web browser 'poll' the server, since that would either introduce too much latency (if the reload delay was large) or put load on the system (if the delay was small)

+1  A: 

If you don't want to use polling, you're more-or-less stuck writing your log viewer completely outside of a browser. However, it's quite simple to write your polling which does a good job of minimizing both latency and system load (as you mentioned concerns about).

The trick to this is to use Comet, which is essentially Ajax + long polling.

Matt Ball
A: 

The HTTP protocol doesn't support PUSH. Your best bet is to let the client fire ajaxical requests at timed intervals. This has a pretty small cost if the data to be sent and retrieved is also small. I can recommend the concise and crossbrowsercompatible jQuery.ajax() in combination with setInterval() for this. You can then use JavaScript (or jQuery) to manipulate the HTML DOM elements representing the log window.

Alternatively (and with a bit more effort) you could make use of Comet technique, which basically simulates the HTTP PUSH / Reverse-Ajax. You're however dependent on the webserver used whether this is supported. Consult the documentation of the server in question using the keyword "Comet". In case of for example Apache Tomcat you can find it here.

Another alternative, if you're using Servlet 3.0, then you can also take benefit of its asynchronous request processing powers as outlined in this article.

BalusC
A: 

Well, since you do say you are willing to do it in javascript:

  • Have your process continuously write, without closing the connection
  • In the client (the browser) use an xmlhttpobject and monitor the ready state.

    0 = uninitialized 1 = loading 2 = loaded 3 = interactive 4 = complete

obviously 3 and 4 are what you are looking after. When you get output, all you have to do is write responseText to a div, and you're set. Look here for xmlhttpobject properties and usage.

nc3b