package org.reldb.rel.v0.server; import java.net.*; import java.io.*; import org.reldb.rel.v0.interpreter.Interpreter; /** A Session represents an active connection to a client. */ public class Session { private static long sessionidgenerator = 0; private Server server; private Socket socket; private boolean running; private long sessionid; /** Create a Session given an open Socket. */ public Session(final Server owner, Socket channel) { sessionid = sessionidgenerator++; InetAddress ip = channel.getInetAddress(); ip.getHostName(); int remotePort = channel.getPort(); System.out.println("Session: Open session " + sessionid + " to " + ip + ":" + remotePort); server = owner; socket = channel; Thread sessionThread = new Thread() { public void run() { try { server.addSession(Session.this); PrintStream output = new PrintStream(socket.getOutputStream()); Interpreter interpreter = new Interpreter(owner.getInstance().getDatabase(), output); running = true; owner.getInstance().announceActive(output); output.println("<EOT>"); output.flush(); while (running) { try { int prefix = socket.getInputStream().read(); if (prefix < 0) break; if (Character.isWhitespace((char)prefix)) continue; if (prefix == 'E') { interpreter.evaluate(socket.getInputStream()).toStream(output); output.println(); } else if (prefix == 'X') { interpreter.interpret(socket.getInputStream()); output.println("\nOk."); } else if (prefix == 'R') { interpreter.reset(); output.println("\nCancel."); } else output.println("ERROR: Rel server protocol error: expected 'R', 'E' or 'X', but got '" + (char)prefix + "'."); } catch (SocketException se) { break; } catch (Throwable t) { interpreter.reset(); output.println("ERROR: " + t.getMessage()); } output.println("<EOT>"); output.flush(); } output.close(); } catch (IOException ioe) { System.out.println("Session: " + ioe); } kill(); } }; sessionThread.start(); } public long getId() { return sessionid; } /** Kill this Session. */ public synchronized void kill() { running = false; server.removeSession(this); if (socket == null) return; try { System.out.println("Session: Close session " + sessionid); socket.close(); socket = null; } catch (IOException ioe) { System.out.println("Session: Unable to close socket " + socket); } } }