2014-09-16 4 views
1

Я кодирование немного веб-сервера Http на основе следующей модели:сеанс обработки в простом сервере HTTP

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 сокета сервера на порт x
  2. Do accept в while
  3. Если новый запрос появляется, обрабатывать запрос в новой резьбе
  4. Ждите другого запроса

Но как я могу реализовать сеанс? Есть ли какой-либо механизм для того, чтобы отличать один сеанс от другого? Как очистить сеанс после закрытия браузера? Как сохранить соединение открытым?

+0

Подождите, я отправлю код – Tony

+0

Какова основная идея внедрения собственного сервера? Чего вы пытаетесь достичь? – tmarwen

+0

@tmarwen, опыт программирования. – Tony

ответ

6

Я не уверен, что вы имеете в виду, поддерживая соединение, но с моей головы я бы создал уникальное (случайное) значение cookie и отправил его клиенту. Это ваш идентификатор сеанса. На сервере вы храните этот идентификатор сеанса в какой-либо карте (ConcurrentHashMap, вероятно, хороший выбор для безопасности потоков) в качестве ключа, и любые данные сеанса будут частью объекта значения.

Когда вы получаете входящее соединение, проверьте, не достает ли файл cookie с известным идентификатором сеанса. Если это так, то вы можете получить объект значения из сеанса HashMap и применить его к текущему соединению.

Если идентификатор сеанса не существует, это означает, что это новый сеанс.

Установив время истечения срока действия файла cookie соответствующим образом (то есть: отрицательное значение для MaxAge), cookie будет удаляться всякий раз, когда сеанс браузера будет закрыт.

1

Как сказал tmarwen сеанс на стороне серверов - это всего лишь карта. Но вам не нужно связывать его с потоком. Просто поместите его на другую карту с идентификатором. Используйте cookeie как удостоверение личности на стороне клиента (браузера), например. Чтобы поддерживать связь, вы можете сохранить свою нить вживую. Подробнее об этом смотрите в HTTP/1.1. Вам также необходимо будет соответствовать статусам и заголовкам, чтобы иметь возможность использовать HTTP.

2

В старые времена, когда php все еще был новым, а cgi - доминирующей «динамической веб-технологией», можно было бы создать временный файл и сообщить клиенту имя файла. Каждый запрос, содержащий это имя файла, по крайней мере изменил бы временную метку последнего имени файла, а задание cron удаляло бы каждый файл, превышающий определенную сумму.

0

До тех пор, пока каждый клиент (браузер) сохраняет свое единственное соединение живым - хотя это редко возможно - вам даже не нужен отдельный сеансовый уровень, потому что ваше (TCP-) соединение является состоятельным, или, способ: ваш сервер может различать клиентов на основе (принятых) объектов Socket.

Для всех остальных случаев существует только несколько других способов, чем использовать куки-файлы (например, отслеживание по пользовательским привычкам - ненадежным или .Net-путь для хранения сериализованного сеанса в HTML и затем данные отправляются из браузеры вместе с каждым запросом). Дмитро и Эрик Б. уже объяснили механизм.

Завершение сеанса на стороне сервера (сеанс очистки после таймаута) немного сложно, поскольку вы должны знать, когда истечет срок действия сеанса, так что ни ваша карта сеанса на стороне сервера не растет до бесконечности, ни сессия не исчезает слишком быстро. (Было бы здорово, если бы не были сбои/отсоединения компьютера из-за сбоя, и каждый пользователь нажимал на выход из системы, прежде чем уйти ...)

Смежные вопросы