简体   繁体   中英

Session handling in simple http server

I was coding a little Http web server based on next model:

public class HttpServer {

    public static void main(String[] args) throws Throwable {
        ServerSocket ss = new ServerSocket(8080);
        while (true) {
            Socket s = ss.accept();
            System.err.println("Client accepted");
            new Thread(new SocketProcessor(s)).start();
        }
    }

    private static class SocketProcessor implements Runnable {

        private Socket s;
        private InputStream is;
        private OutputStream os;

        private SocketProcessor(Socket s) throws Throwable {
            this.s = s;
            this.is = s.getInputStream();
            this.os = s.getOutputStream();
        }

        public void run() {
            try {
                readInputHeaders();
                writeResponse("<html><body><h1>Hello</h1></body></html>");
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                try {
                    s.close();
                } catch (Throwable t) {
                   t.printStackTrace();
                }
            }
            System.err.println("Client processing finished");
        }

        private void writeResponse(String s) throws Throwable {
            String response = "HTTP/1.1 200 OK\r\n" +
                    "Server: YarServer/2009-09-09\r\n" +
                    "Content-Type: text/html\r\n" +
                    "Content-Length: " + s.length() + "\r\n" +
                    "Connection: close\r\n\r\n";
            String result = response + s;
            os.write(result.getBytes());
            os.flush();
        }

        private void readInputHeaders() throws Throwable {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while(true) {
                String s = br.readLine();
                if(s == null || s.trim().length() == 0) {
                    break;
                }
            }
        }
    }
}
  1. Run server socket on port x
  2. Do accept in while
  3. If new request appears, handle request in new thread
  4. Wait for another request

But how can I implement a session? Is there any mechanism to differ one session from another? How to clean session after closing a browser? How to keep a connection open?

I'm not sure what you mean by a keeping a connection option, but off the top of my head, I would create a unique (random) cookie value and send it back to the client. This is your session id. On the server, you store this session id in a map of some sort (ConcurrentHashMap probably a good choice for thread safety) as the key, and any specific session data would be part of the value object.

When you receive an incoming connection, check to see if it supplies a cookie with a known session id. If so, then you can retrieve the value object from your Session HashMap and apply it to your current connection.

If the session id does not exist, it means it is a new session.

By setting the cookie expiration time appropriately, (ie: negative value for MaxAge), the cookie will be deleted whenever the browser session is closed.

In the old days, when php was still new and cgi was the dominating "dynamic web technology", one would generate a temportary file and tell the client the file name. Every request holding this file name would at least alter the file name's last access timestamp and a cron job would delete every file older than a certain amount.

As tmarwen said session on servers side is just a map. But you don't need to link it to a thread. Just put it into another map with ID. Use coockie as ID holder on client side (browser) for instance. To keep connection you can keep your thread live. More on this look in HTTP/1.1 a keep-alive-mechanism. You will need to conform with statuses and headers as well to be able to use HTTP.

As long as each client (browser) keeps his own single connection alive - though it is seldomly possible - you don't even need a separate session layer because your (TCP-)connection is stateful, or to put it another way: your server can distinguish between clients on the basis of (accepted) Socket objects.

For all other cases there are only a few other ways than to use cookies (for example, tracking by user habits - unreliable; or the .Net way to store the serialized session in HTML and that data is then posted from the browsers along with every request). Dmytro and Eric B. both already explained the mechanism.

Server-side session expiration (clearing session after timeout) is a bit tricky because you have to know when exactly a session may expire so that neither your server-side session map grows to infinity nor any session vanishes too quickly. (It would be great if there were no computer crashes / disconnects because of failure, and every user would click on logout before leaving...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM