[英]Session handling in simple http server
我正在基於下一個模型編寫一個小的Http Web服務器:
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;
}
}
}
}
}
x
上運行服務器套接字 accept
的while
但是我該如何實施會議? 是否有任何機制可以將一個會話與另一個會話區分開? 關閉瀏覽器后如何清理會話? 如何保持連接打開?
我不確定保留連接選項是什么意思,但是我想創建一個唯一的(隨機)cookie值並將其發送回客戶端。 這是您的會話ID。 在服務器上,您將此會話ID存儲在某種映射中(ConcurrentHashMap可能是線程安全的一個不錯的選擇)作為鍵,並且任何特定的會話數據都將是value對象的一部分。
當您收到傳入連接時,請檢查其是否提供了具有已知會話ID的cookie。 如果是這樣,則可以從Session HashMap中檢索value對象並將其應用於當前連接。
如果會話ID不存在,則表示它是一個新會話。
通過適當設置cookie的有效時間(即MaxAge的負值),只要關閉瀏覽器會話,就將刪除cookie。
在過去,當php仍然很新,而cgi是主導的“動態Web技術”時,會生成一個臨時文件並告訴客戶端文件名。 持有此文件名的每個請求都將至少更改文件名的最后訪問時間戳,而cron作業將刪除每個早於一定數量的文件。
正如tmarwen所說,在服務器端的會話只是一張地圖。 但是您不需要將其鏈接到線程。 只需將其放入具有ID的另一張地圖中即可。 例如,將coockie用作客戶端(瀏覽器)上的ID持有人。 要保持連接,您可以保持線程活動。 在HTTP / 1.1中,關於這種外觀的更多信息是保持活動機制。 您還需要符合狀態和標頭才能使用HTTP。
只要每個客戶端(瀏覽器)都保持自己的單個連接處於活動狀態(盡管這種情況很少發生),您甚至不需要一個單獨的會話層,因為您的(TCP-)連接是有狀態的,或者換句話說:您的服務器可以基於(接受的)Socket對象在客戶端之間進行區分。
對於所有其他情況,除了使用Cookie之外,只有幾種其他方法(例如,按用戶習慣進行跟蹤-不可靠;或者.Net方法將序列化會話存儲為HTML,然后將數據從瀏覽器中與每個請求)。 Dmytro和Eric B.都已經解釋了該機制。
服務器端會話期滿(超時后清除會話)有點棘手,因為您必須知道會話何時可能確切到期,以便服務器端會話映射不會增長到無限,也不會消失太快。 (如果沒有由於故障而導致計算機崩潰/斷開連接,並且每個用戶在離開前都單擊注銷,那將是非常不錯的選擇。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.