Link to home
Start Free TrialLog in
Avatar of fredand44
fredand44

asked on

How to Server Push when Event has occured?

X Hello!

Does anyone got a better solution for this?

What I need to create is a servlet that uses Server side Push/Server sid Reload. When something happens a page should be reloaded.

Suppose that you got a visit counter at a page in a browser and if that counter is updated from an other page in an other browser all other page in all browsers with that counter needs to be updated.

I have created a ugly hack that produce this, but I'm not satisfied with it. My hack does a file access every second and I do not want that.

What I would like is some Listener that listens if perhaps the file is changed or some other Event has occur on the server side but I do not know if that is possible.

Below is my ugly hack divided in 2 Servlets. My FileManager just reads a number from a file, nothing magic.

So if any one got a nice solution please let me know!

BTW Server side Push doesn't work in Internet Explorer I use a old NetScape at Linux Mandrake 8.0 that works fine. I have heard that it is possible with FireFox as well.

Best regards
Fredrik

The servlets that checks for changes:

package my.servlets;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

import my.servlets.*;
import my.tools.*;

import com.oreilly.servlet.*;
import com.oreilly.servlet.multipart.*;

public class ServerReload extends GeneralServlet
{
    public void start(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
        ServletOutputStream out = response.getOutputStream();
        MultipartResponse multi = new MultipartResponse(response);

        int counter = 0;
        while(counter < 100)
        {
            String output = FileManager.getStringFor("counter.txt");
            int tempCounter = Integer.parseInt(output);

            if(counter != tempCounter)
            {
                multi.startResponse("text/plain");
                counter = tempCounter;
                out.println(counter);
                multi.endResponse();
            }

            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
            }
        }
        multi.finish();
        out.close();
    }
}


The servlet that updates the counter.txt file:

package my.servlets.assignments1;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

import my.servlets.*;
import my.tools.*;

public class SecureFileAccess extends GeneralServlet
{
    public void start(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
        response.setContentType("text/plain");
        out = new PrintWriter(response.getOutputStream());

        String output = null;
        synchronized(this)
        {
            try
            {
                output = FileManager.getStringFor("counter.txt");
                int counter = Integer.parseInt(output);
                output = ""+(++counter);
                FileManager.writeString("counter.txt", output, false);
            }
            catch(Exception e)
            {
                output = "1";
                FileManager.writeString("counter.txt", output, false);
            }
        }

        printString(output);
        flush();
    }
}
ASKER CERTIFIED SOLUTION
Avatar of kiranhk
kiranhk

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of fredand44
fredand44

ASKER

Hello Mates!
I solved it like this, not the best way but I guess that it will work.

public class ServerReload_1g extends GeneralServlet implements HttpSessionAttributeListener
{
      static boolean send = false;

      public void start(HttpServletRequest request, HttpServletResponse response) throws IOException
      {
            ServletOutputStream servletOutputStream = response.getOutputStream();
            MultipartResponse multipartResponse = new MultipartResponse(response);

            send = true;

            int counter = 0;

            while(counter < 100)
            {
                  if(send)
                  {
                        String output = FileManager.getStringFor("applications/int_2/int_2/templates/1a.txt");
                        counter = Integer.parseInt(output);
                        multipartResponse.startResponse("text/plain");
                        servletOutputStream.println(counter);
                        multipartResponse.endResponse();
                        send = false;
                  }

                  try
                  {
                        Thread.sleep(1000);
                        counter++;
                  }
                  catch (InterruptedException e)
                  {
                  }
            }
            multipartResponse.finish();
            servletOutputStream.close();

      }

      public void attributeAdded(HttpSessionBindingEvent se)
      {
            send = true;
      }

      public void attributeRemoved(HttpSessionBindingEvent se)
      {
      }

      public void attributeReplaced(HttpSessionBindingEvent se)
      {
      }
}


public class SecureFileAccess_1a extends GeneralServlet
{
      public void start(HttpServletRequest request, HttpServletResponse response) throws IOException
      {
            response.setContentType("text/plain");
            out = new PrintWriter(response.getOutputStream());

            String output = null;
            synchronized(this)
            {
                  try
                  {
                        output = FileManager.getStringFor("applications/int_2/int_2/templates/1a.txt");
                        int counter = Integer.parseInt(output);
                        output = ""+(++counter);
                        FileManager.writeString("applications/int_2/int_2/templates/1a.txt", output, false);
                  }
                  catch(Exception e)
                  {
                        output = "1";
                        FileManager.writeString("applications/int_2/int_2/templates/1a.txt", output, false);
                  }
            }

            //Just notify the listener in ServerReload_1g that we have updated the counter
            session.setAttribute("ServerReload_1g", "ServerReload_1g");
            session.removeAttribute("ServerReload_1g");
            //It is possible to work around the listeners with using the static variable send direct.
            //ServerReload_1g.send = true;

            printString(output);
            flush();
      }
}

Thanks for your time!
Fredrik