基于WebSocket协议的Netty开发
WebSocket是一种在单个TCP连接上进行全双工通信的协议。在这篇博客中,我们将使用Netty开发一个基于WebSocket协议的实时聊天系统。
1. 环境准备
首先,我们需要在项目中引入Netty的依赖。在Maven项目中,添加以下依赖:
1
2
3
4
5
|
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.65.Final</version>
</dependency>
|
2. WebSocket服务器开发
2.1 创建WebSocketHandler
首先,我们需要创建一个处理WebSocket通信的Handler。这里我们自定义一个WebSocketHandler,用于处理客户端的消息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
// 连接建立时发送欢迎消息
ctx.channel().writeAndFlush(new TextWebSocketFrame("欢迎连接WebSocket服务器!"));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
// 接收客户端消息并广播
String text = msg.text();
System.out.println("收到客户端消息:" + text);
// 遍历所有连接的Channel
for (Channel channel : ctx.channel().parent().children()) {
// 广播消息
if (channel != ctx.channel()) {
channel.writeAndFlush(new TextWebSocketFrame(text));
} else {
channel.writeAndFlush(new TextWebSocketFrame("自己:" + text));
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
|
在这个WebSocketHandler中,我们重写了handlerAdded
方法,用于在连接建立时发送欢迎消息。重写了channelRead0
方法,用于接收客户端的消息并广播给所有连接的客户端。
2.2 创建WebSocketServer
接下来,我们创建一个WebSocket服务器,绑定端口并启动:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public class WebSocketServer {
public static void main(String[] args) throws Exception {
// 创建EventLoopGroup
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 创建ServerBootstrap
ServerBootstrap bootstrap = new ServerBootstrap();
// 设置参数
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 添加WebSocketHandler前的编码解码器
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new WebSocketServerProtocolHandler("/websocket"));
// 添加WebSocketHandler
ch.pipeline().addLast(new WebSocketHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口并启动
ChannelFuture future = bootstrap.bind(8080).sync();
// 等待服务器关闭
future.channel().closeFuture().sync();
} finally {
// 释放资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
|
在这个WebSocketServer中,我们创建了两个EventLoopGroup用于处理客户端连接和IO操作,然后创建了一个ServerBootstrap,设置了相关参数,并添加了我们之前创建的WebSocketHandler。在添加WebSocketHandler之前,我们还添加了一些编码解码器,用于处理WebSocket通信。最后,我们绑定了8080端口并启动了服务器。
3. WebSocket客户端开发
接下来,我们使用JavaScript开发一个简单的WebSocket客户端,用于连接我们的WebSocket服务器并进行实时聊天。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket客户端</title>
</head>
<body>
<input type="text" id="message" placeholder="请输入消息">
<button onclick="sendMessage()">发送</button>
<div id="content"></div>
<script>
// 创建WebSocket连接
const socket = new WebSocket("ws://localhost:8080/websocket");
// 连接成功时的回调函数
socket.onopen = function () {
console.log("连接成功");
};
// 接收服务器消息时的回调函数
socket.onmessage = function (event) {
const content = document.getElementById("content");
content.innerHTML += "<p>" + event.data + "</p>";
};
// 发送消息
function sendMessage() {
const message = document.getElementById("message").value;
socket.send(message);
}
</script>
</body>
</html>
|
在这个WebSocket客户端中,我们创建了一个WebSocket连接,并设置了连接成功和接收服务器消息时的回调函数。在发送消息时,我们获取输入框中的消息并通过WebSocket连接发送给服务器。
4. 测试
现在,我们可以使用浏览器打开我们的WebSocket客户端,连接我们的WebSocket服务器,并进行实时聊天了。
5. 总结
在这篇博客中,我们使用Netty开发了一个基于WebSocket协议的实时聊天系统。通过创建WebSocketHandler处理客户端消息,并创建WebSocketServer绑定端口并启动,我们实现了一个可以进行实时通信的WebSocket服务器。同时,我们还使用JavaScript开发了一个简单的WebSocket客户端,用于连接我们的WebSocket服务器并进行实时聊天。当然,这只是一个简单的示例,实际开发中可能需要处理更复杂的情景,但这个示例已经展示了基于WebSocket协议的Netty开发的基本思路。