Java 简单http服务器中的会话处理
我正在基于下一个模型编写一个小型Http web服务器:Java 简单http服务器中的会话处理,java,session,Java,Session,我正在基于下一个模型编写一个小型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.
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;
}
}
}
}
}
公共类HttpServer{
公共静态void main(字符串[]args)抛出可丢弃的{
ServerSocket ss=新的ServerSocket(8080);
while(true){
套接字s=ss.accept();
系统错误打印号(“客户接受”);
新线程(新SocketProcessor)).start();
}
}
私有静态类SocketProcessor实现可运行{
私人插座;
私有输入流是;
私有输出流;
专用SocketProcessor(套接字s)抛出可丢弃的{
这个.s=s;
this.is=s.getInputStream();
this.os=s.getOutputStream();
}
公开募捐{
试一试{
readinputhreaders();
书面回复(“你好”);
}捕获(可丢弃的t){
t、 printStackTrace();
}最后{
试一试{
s、 close();
}捕获(可丢弃的t){
t、 printStackTrace();
}
}
System.err.println(“客户端处理完成”);
}
私有void writeResponse(字符串s)抛出可丢弃{
String response=“HTTP/1.1 200正常\r\n”+
“服务器:YarServer/2009-09-09\r\n”+
“内容类型:text/html\r\n”+
内容长度:“+s.Length()+”\r\n+
“连接:关闭\r\n\r\n”;
字符串结果=响应+s;
write(result.getBytes());
os.flush();
}
私有void readinputhreaders()抛出可丢弃的{
BufferedReader br=新的BufferedReader(新的InputStreamReader(is));
while(true){
字符串s=br.readLine();
如果(s==null | | s.trim().length()==0){
打破
}
}
}
}
}
x上运行服务器套接字
但是如何实现会话呢?是否有任何机制将一个会话与另一个会话区分开来?如何在关闭浏览器后清理会话?如何保持连接打开 正如tmarwen所说,服务器端的会话只是一张地图。但您不需要将其链接到线程。只需将其放入另一个ID为的地图中。例如,在客户端(浏览器)使用coockie作为ID持有者。要保持连接,您可以保持线程处于活动状态。HTTP/1.1是一种保持活动的机制,详细介绍了这一点。您需要符合状态和标题,才能使用HTTP。正如tmarwen所说,服务器端的会话只不过是一张地图。但您不需要将其链接到线程。只需将其放入另一个ID为的地图中。例如,在客户端(浏览器)使用coockie作为ID持有者。要保持连接,您可以保持线程处于活动状态。HTTP/1.1是一种保持活动的机制,详细介绍了这一点。您需要符合状态和标题,才能使用HTTP。我不确定您所说的保持连接选项是什么意思,但在我的脑海中,我会创建一个唯一(随机)cookie值并将其发送回客户端。这是您的会话id。在服务器上,您将此会话id存储在某种映射(ConcurrentHashMap可能是线程安全的一个很好选择)中作为密钥,并且任何特定的会话数据都将是value对象的一部分 当您收到传入连接时,请检查它是否提供具有已知会话id的cookie。如果是,则可以从会话HashMap中检索value对象并将其应用于当前连接 如果会话id不存在,则表示它是一个新会话
通过适当设置cookie过期时间(即:MaxAge为负值),每当浏览器会话关闭时,cookie都将被删除。我不确定保留连接选项是什么意思,但我会创建一个唯一(随机)cookie值并将其发送回客户端。这是您的会话id。在服务器上,您将此会话id存储在某种映射(ConcurrentHashMap可能是线程安全的一个很好选择)中作为密钥,并且任何特定的会话数据都将是value对象的一部分 当您收到传入连接时,请检查它是否提供具有已知会话id的cookie。如果是,则可以从会话HashMap中检索value对象并将其应用于当前连接 如果会话id不存在,则表示它是一个新会话
通过适当设置cookie过期时间(即:MaxAge为负值),每当浏览器会话关闭时,cookie将被删除。在过去,当php还是新的,cgi是主要的“动态web技术”时,人们会生成一个临时文件并告诉客户机文件名。持有此文件名的每个请求至少会更改文件名的上次访问时间戳,cron作业会删除所有超过一定数量的文件。在过去,当php还是新的,cgi是主要的“动态web技术”时,会生成一个临时文件并告诉客户文件名。持有此文件名的每个请求都将至少更改文件名的上次访问时间戳,并且cron作业将删除超过一定数量的所有文件。只要每个客户端(浏览器)保持自己的单个连接处于活动状态(尽管这是极有可能的),您甚至不需要单独的会话层,因为您的(TCP-)连接是有状态的,或者换句话说:服务器可以根据(接受的)套接字对象区分客户端 对于所有其他情况,除了使用cookie之外,只有几种其他方法