Skip to content

Commit f7902da

Browse files
author
litongjava
committed
update HttpServer
1 parent 9e77bf9 commit f7902da

File tree

1 file changed

+36
-24
lines changed
  • frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server

1 file changed

+36
-24
lines changed

frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/HttpServer.java

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.nio.channels.AsynchronousSocketChannel;
88
import java.nio.channels.CompletionHandler;
99
import java.nio.charset.StandardCharsets;
10+
import java.time.ZonedDateTime;
11+
import java.time.format.DateTimeFormatter;
12+
import java.time.ZoneId;
1013
import java.util.concurrent.ThreadFactory;
1114

1215
import com.alibaba.fastjson.JSON;
@@ -26,31 +29,29 @@ public class HttpServer {
2629

2730
public static void main(String[] args) throws Exception {
2831

29-
// 创建通道提供者,false 表示非低内存模式
32+
// 创建异步通道提供者
3033
EnhanceAsynchronousChannelProvider provider = new EnhanceAsynchronousChannelProvider(false);
3134

32-
// 创建一个异步通道组,线程数设为2(根据需求调整)
35+
// 创建通道组
3336
AsynchronousChannelGroup group = provider.openAsynchronousChannelGroup(2, new ThreadFactory() {
3437
@Override
3538
public Thread newThread(Runnable r) {
3639
return new Thread(r, "http-server-thread");
3740
}
3841
});
3942

40-
// 使用提供者创建服务器通道
43+
// 创建服务器通道并绑定端口
4144
EnhanceAsynchronousServerSocketChannel server = (EnhanceAsynchronousServerSocketChannel) provider.openAsynchronousServerSocketChannel(group);
42-
// 绑定端口,例如 80,设置 backlog
4345
server.bind(new InetSocketAddress(8080), 0);
4446

4547
System.out.println("HTTP Server 正在监听端口 8080 ...");
4648

47-
// 异步接受连接请求
49+
// 异步接受连接
4850
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
4951
@Override
5052
public void completed(AsynchronousSocketChannel channel, Object attachment) {
51-
// 接收到连接后,立即继续接受下一个连接
53+
// 继续接收其他连接
5254
server.accept(null, this);
53-
// 处理客户端连接
5455
handleClient(channel);
5556
}
5657

@@ -60,16 +61,14 @@ public void failed(Throwable exc, Object attachment) {
6061
}
6162
});
6263

63-
// 主线程阻塞,以保证服务器运行
64+
// 主线程阻塞
6465
Thread.currentThread().join();
6566
}
6667

6768
private static void handleClient(AsynchronousSocketChannel channel) {
68-
// 通过 BufferPage 池化获取一个 VirtualBuffer,分配 8192 字节空间
6969
VirtualBuffer virtualBuffer = bufferPage.allocate(8192);
7070
ByteBuffer buffer = virtualBuffer.buffer();
7171

72-
// 异步读取客户端请求,将 VirtualBuffer 作为附件传入
7372
channel.read(buffer, virtualBuffer, new CompletionHandler<Integer, VirtualBuffer>() {
7473
@Override
7574
public void completed(Integer result, VirtualBuffer attachment) {
@@ -78,25 +77,42 @@ public void completed(Integer result, VirtualBuffer attachment) {
7877
buffer.flip();
7978
byte[] bytes = new byte[buffer.remaining()];
8079
buffer.get(bytes);
81-
// 将请求转换成字符串进行判断
8280
String request = new String(bytes, StandardCharsets.UTF_8);
83-
81+
82+
// 生成当前时间,格式为 RFC 1123 格式
83+
String date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneId.of("GMT")));
84+
8485
ByteBuffer responseBuffer;
85-
// 如果请求以 "GET /plaintext" 开头,则直接返回 HELLO_WORLD_BYTES
8686
if (request.startsWith("GET /plaintext")) {
87-
String httpResponse = "HTTP/1.1 200 OK\r\n" + "Content-Length: 13\r\n" + "Server: aio-socket\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "Hello, World!";
87+
String body = "Hello, World!";
88+
String httpResponse = "HTTP/1.1 200 OK\r\n" +
89+
"Content-Length: " + body.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
90+
"Server: aio-socket\r\n" +
91+
"Content-Type: text/plain\r\n" +
92+
"Date: " + date + "\r\n" +
93+
"\r\n" +
94+
body;
8895
responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
8996

9097
} else if (request.startsWith("GET /json")) {
9198
String jsonString = JSON.toJSONString(new Message(HELLO_WORLD));
92-
int length = jsonString.length();
93-
String httpResponse = "HTTP/1.1 200 OK\r\n" + "Content-Length: " + length + "\r\n" + "Server: aio-socket\r\n" + "Content-Type: application/json\r\n" + "\r\n" + jsonString;
94-
99+
int length = jsonString.getBytes(StandardCharsets.UTF_8).length;
100+
String httpResponse = "HTTP/1.1 200 OK\r\n" +
101+
"Content-Length: " + length + "\r\n" +
102+
"Server: aio-socket\r\n" +
103+
"Content-Type: application/json\r\n" +
104+
"Date: " + date + "\r\n" +
105+
"\r\n" +
106+
jsonString;
95107
responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
96-
97108
} else {
98-
// 默认返回完整的 HTTP 响应
99-
String httpResponse = "HTTP/1.1 200 OK\r\n" + "Content-Length: 13\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "Hello, World!";
109+
String body = "Hello, World!";
110+
String httpResponse = "HTTP/1.1 200 OK\r\n" +
111+
"Content-Length: " + body.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
112+
"Content-Type: text/plain\r\n" +
113+
"Date: " + date + "\r\n" +
114+
"\r\n" +
115+
body;
100116
responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
101117
}
102118

@@ -109,7 +125,6 @@ public void completed(Integer result, VirtualBuffer attachment) {
109125
} catch (IOException e) {
110126
e.printStackTrace();
111127
} finally {
112-
// 写完响应后归还虚拟缓冲区
113128
attachment.clean();
114129
}
115130
}
@@ -122,13 +137,11 @@ public void failed(Throwable exc, VirtualBuffer attachment) {
122137
} catch (IOException e) {
123138
e.printStackTrace();
124139
} finally {
125-
// 出现写异常时也归还虚拟缓冲区
126140
attachment.clean();
127141
}
128142
}
129143
});
130144
} else {
131-
// 未读到数据,则关闭连接
132145
try {
133146
channel.close();
134147
} catch (IOException e) {
@@ -137,7 +150,6 @@ public void failed(Throwable exc, VirtualBuffer attachment) {
137150
}
138151
} finally {
139152
// 注意:如果在写操作中已经归还了虚拟缓冲区,则不要重复释放
140-
// attachment.clean();
141153
}
142154
}
143155

0 commit comments

Comments
 (0)