Reputation: 2122
I'm using a simple http server and created a context to print my logger output.
server.createContext("/log", new HttpHandler() {
@Override
public void handle(final HttpExchange t) throws IOException {
t.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8");
t.sendResponseHeaders(200, 0);
Writer out = new OutputStreamWriter(t.getResponseBody(), "UTF-8");
out.write("<pre>");
Semaphore s = new Semaphore(0);
ExecutionContext.setLogger(new ILogger() {
@Override
public void log(String message) {
try {
out.write(message);
out.flush();
} catch (IOException e) {
s.release();
}
}
});
try {
s.acquire();
} catch (InterruptedException e) {
}
}
The OutputStream is never closed, unless the connexion ends (for example, the user closes the browser tab). It's working as expected, except that my browser is not scrolling to the new data when available.
I know it's possible to scroll to a div using javascript but I can't find a nice method to do this (I would need to call the javascript code each time new data is available, and even if I could, the div wouldn't be at the end of the page, because the page is always updating...)
Do you have a solution?
Thanks
EDIT: Solution inspired by Sen Jacob's answer : server.createContext("/log", new HttpHandler() {
@Override
public void handle(final HttpExchange t) throws IOException {
t.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8");
t.sendResponseHeaders(200, 0);
Writer out = new OutputStreamWriter(t.getResponseBody(), "UTF-8");
StringBuilder sb = new StringBuilder();
sb.append("<html>\n");
sb.append("<body>\n");
sb.append("<pre id='logger'></pre>\n");
sb.append("<script>\n");
sb.append("var logger = document.getElementById('logger');\n");
sb.append("\n");
sb.append("function addLog(s) {\n");
sb.append(" // scroll only if already at the end of the page\n");
sb.append(" var scroll = document.body.scrollTop + document.body.clientHeight == document.body.scrollHeight\n");
sb.append(" logger.innerHTML += s;\n");
sb.append(" if(scroll) {\n");
sb.append(" window.scrollTo(0,document.body.scrollHeight);\n");
sb.append(" }\n");
sb.append("}</script>\n");
out.write(sb.toString());
Semaphore s = new Semaphore(0);
ExecutionContext.setLogger(new ILogger() {
@Override
public void log(String message) {
try {
message = StringEscapeUtils.escapeEcmaScript(message);
out.write("\n<script>addLog('" + message + "')</script>");
out.flush();
} catch (IOException e) {
s.release();
}
}
});
try {
s.acquire();
} catch (InterruptedException e) {
}
}
Upvotes: 0
Views: 86
Reputation: 3442
Here is an example javascript code where you can scroll to newly added log entry.
var logger = document.getElementById("logger");
function addLog() {
// add new log entry
var div = document.createElement("div");
div.innerHTML = "log - " + Date.now();
logger.appendChild(div);
// scroll to new log
logger.scrollTop = logger.scrollHeight;
}
// simulate http response
var timer = setInterval(addLog, 1000);
window.onbeforeunload = clearInterval.bind(window, timer);
#logger {
height: 10em;
overflow-y: auto;
}
<div id="logger"></div>
Upvotes: 3