Among the COMET,SOCKETS,SSE i felt server sent events is easy to implement.
And i am using tomcat server so i used servlets to implement SSE.
But i am facing big problem here and searched a lot but i did not got any solution to it.
The problem is if you see the basic example at sever sent event
The output is repeating for every 4-seconds,can't we make it to change output in same line.
In detail:
After 4 seconds a new updated result is printing in next line of previous output,
i want it to be printed in the same line of previous output(over write on previous output) and it should looks like a digital watch.
And my servlet code is like this what kind of changes i have to do.
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/SseServer")
public class SseServer extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/event-stream;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Connection", "keep-alive");
PrintWriter out = response.getWriter();
while (true) {
out.print("id: " + "ServerTime" + "\n");
out.print("data: " + new Date().toLocaleString() + "\n\n");
out.flush();
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I thought using while loop make it as a repeated result.
GREAT THANKS FOR ANY HELP
The example you linked to uses the following code:
document.getElementById("result").innerHTML += event.data + "<br>";
So, it appends the new event data to the content of the result element. To replace it, just change it to
document.getElementById("result").innerHTML = event.data + "<br>";
In short, your question doesn't have anything to do with how you produce the event at server-side, but everything to do with how you consume the event, in the browser.
Related
I am new to web programming. I am using this simple code in my get method
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<html><head><title>Guest Book</title></head><body>" );
out.println(" </body></html> ");
I am getting the below error while clicking on run on server
enter image description here
Note: When i removed the html code, the servlet is working fine.Is it my Html code problem or any tomcat sevrver issue.
The servlet is in my package cs3220homework and servlet name is #WebServlet("/MainFolder").
I tried everywhere to look for the issue and i was not able to find it.If its duplicate please let me know.
Thanks for your reply
Harminder
Its working fine. App is named Test and Servlet class is also named Test. This is the url http://localhost:8080/Test/Test
package foo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/Test")
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<html><head><title>Guest Book</title></head><body>" );
out.println(" </body></html> ");
}
}
everyone.
If an error is occurred after committing a part of data to HttpServletResponse,
can I send error messages or replace http status code?
I investigated some functions (sendError, sendStatus, etc.), but I wasn't able to find a solution.
It's usual, isn't it?
If so, servers need to store all data before sending a lot data.
I think that servers can never have enough memories.
p.s.
I must send a lot data such as video data. It's so big data, so I don't want to store a lot data before sending. Umm :-(
You can try to increase the buffer and reset it if error occurs. This could help you to "patch" your code. But with video-content it could be probably difficult.
You can experiment with the following code.
http://localhost:8080/BufferedResponse?flash
http://localhost:8080/BufferedResponse
The Servlet:
package testingThings;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/BufferedResponse")
public class BufferedResponse extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("buffer size: " + response.getBufferSize());
response.setStatus(HttpServletResponse.SC_OK);
String flash = request.getParameter("flash");
if (flash != null) {
response.flushBuffer();
}
if (response.isCommitted()) {
response.getWriter().println("buffer was commited.");
response.getWriter().println("it is too late change the response");
}
else {
response.resetBuffer();
response.getWriter().println("buffer reseted.");
response.getWriter().println("response and status code were changed");
response.setStatus(HttpServletResponse.SC_FOUND);
}
}
}
Or like others suggested, separate the logic from the view.
At least you can process the data, write "log" (as preparation for response). If everything was ok and no error occurs, write the "log" in the response.
The thing I try to implement the method getPathTranslated () but always returns null, this is the method I use:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FileLocation extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//response.setContentType("text/html;charset=UTF-8");
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
if (request.getPathInfo() != null) {
out.println("The file \"" + request.getPathInfo() + "\"");
out.println("Is stored at \"" + request.getPathTranslated() + "\"");
} else {
out.println("Path info is null, no file to lookup");
}
}
}
If you are trying to retrieve the filesystem path corresponding to a URL path, try getServletContext().getRealPath("your_path").
Try this line:
request.getRequestURI().substring(request.getContextPath().length())
In situations where the servlet container cannot determine a valid file path for getRealPath or getPathTranslated methods, such as when the Web application is executed from an archive, on a remote file system not accessible locally, or in a database, these methods must return null.
The getPathTranslated method computes the real path of the pathInfo of the request.
If there is not a situation check your Servlet Mapping in deployment descriptor.
If you have a situation like:
<url-pattern>*.xhtml</url-pattern>
then you must know that observed path element behavior is like following (assume your request path is /myapp/admin/mypage.xhtml)
ContextPath: /myapp
ServletPath: /admin/mypage.xhtml
PathInfo: null
Hope it will help you to analyze a problem from a different point of view.
I have a very simple SSE (Server Sent Event of Html5) with Java used on the server side. I have included both the client and the server below. The problem is that if I change the server side, even a simple change such as changing the text in a debug output, which has nothing to do with the actual text sent to the server, the client stops posting the received messages. Based on the output message being printed out on the server side, and on the request traffic that I see both in Firebug, and in Chrome's developer tool, I can see that the server is sending messages, and the browser receives the message. The only problem is that the JavaScript function that is supposed to be triggered when SSE is received is not being triggered. Any suggestion, or do you see anything wrong with my code?
<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource)!=="undefined")
{
var source=new EventSource("/ServerSideForSSE/sse3");
source.onmessage=function(event)
{
document.getElementById("result").innerHTML+=event.data + "<br>";
};
}
else
{
document.getElementById("result").innerHTML=
"Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
package com.ultratech;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/sse3")
public class sse3 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setCharacterEncoding("utf-8");
response.setContentType("text/event-stream");
PrintWriter out = response.getWriter();
int x = 0;
while (x < 100)
{
x++;
Date currentTime_1 = new Date();
out.println("Current Time is: " + currentTime_1);
out.println();
out.flush();
System.out.println("Another message sent to the cleint ...");
if (x > 100) {System.exit(0);}
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//End of for().
out.close();
}//End of doGet().
}
Each message that you send MUST start with the string "data:" (not including the quotes), and must be followed with a blank line.
If you don't follow this syntax, then the client doesn't consider what you send as a message, and thus the function is not triggered.
I'm building a web application from an existing project. In the existing project I have a class that contains all my objects and the things I can do with them.
I was wondering what will happen if I had an instance of this class to a servlet as a data member:
When the same user with same session is directed to the servlet that contains this class will it keep it's data or will it regenerate every time?
Will every user/session have a different copy of this member or is it shared?
If data members in servlets don't keep thir state for the same session, then what do you recommend? Maybe activly adding it to the session?
Thanks for your help
Servlets - thus their data members - are shared between all sessions on the server. Thus
When the same user with same session is directed to the servlet that contains this class will it keep it's data or will it regenerate every time?
The data will be kept around (for all users) until you restart the web application.
Will every user/session have a different copy of this member or is it shared?
It is shared.
If data members in servlets don't keep thir state for the same session, then what do you recommend? Maybe activly adding it to the session?
Session specific data should be stored in an HttpSession.
To be sure of this behavior, I wrote a little TestingServlet - I will show you the lifecycle of a servlet and its members. Also supplied; How to work with session variables
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Basic servlet for lifecycle testing
*
* #author powermicha
*
*/
public class TestingServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 4020575563844924588L;
private Logger logger;
private int requestCounter;
#Override
public void init() throws ServletException {
logger = Logger.getLogger("TestingServlet_" + System.currentTimeMillis());
logger.log(Level.INFO, "TestingServlet initialized");
requestCounter = 0;
}
#Override
public void destroy() {
logger.log(Level.INFO, "TestingServlet destroyed");
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int requestsPerSession = incrementRequestsPerSession(req);
String logMessage = "TestingServlet was called " + (++requestCounter) + " times. "
+ requestsPerSession + " times from the same session (ID:"
+ req.getSession().getId() + ")";
logger.log(Level.INFO, logMessage);
// send it to the browser
PrintWriter writer = resp.getWriter();
writer.write(logMessage);
writer.close();
}
private int incrementRequestsPerSession(HttpServletRequest req) {
Integer counter = (Integer) req.getSession().getAttribute("requestsPerSession");
if (counter == null) {
counter = 1;
} else {
counter++;
}
req.getSession().setAttribute("requestsPerSession", counter);
return counter;
}
}