一、WebSocket服务器基础概念
1.1 WebSocket简介
WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许服务端主动向客户端推送数据,解决了HTTP协议只能由客户端发起请求的问题。
1.2 Netty框架优势
- 高性能:基于NIO的异步事件驱动模型
- 可扩展性:灵活的管道机制,易于扩展
- 成熟稳定:被广泛应用在各种高并发场景
二、核心代码解析
2.1 服务器初始化
java
@PostConstruct
public void init() {
new Thread(() -> {
try {
start();
} catch (InterruptedException e) {
log.error("启动WebSocket服务器失败!", e);
}
}).start();
}
使用@PostConstruct注解确保Spring容器初始化完成后自动启动WebSocket服务器。
2.2 线程组配置
java
// 主线程组:处理客户端连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
// 工作线程组:处理连接后的I/O操作
EventLoopGroup workGroup = new NioEventLoopGroup();
- bossGroup:负责接受新连接
- workGroup:负责处理已建立连接的I/O操作
2.3 ChannelPipeline配置
java
pipeline.addLast(new HttpServerCodec()); // HTTP编解码器
pipeline.addLast(new HttpObjectAggregator(65535)); // HTTP消息聚合器
pipeline.addLast(new WebSocketServerProtocolHandler("/testWs")); // WebSocket协议处理器
三、实际应用案例
3.1 场景:实时聊天室
案例背景
假设我们需要构建一个简单的实时聊天室,用户可以加入聊天室并实时接收其他用户发送的消息。
服务器端实现要点
- 使用
ChannelGroup管理所有连接的客户端 - 在
handlerAdded()方法中添加新连接到群组 - 在
handlerRemoved()方法中移除断开的连接
客户端HTML示例
html
<!DOCTYPE html>
<html>
<head>
<title>WebSocket聊天室</title>
</head>
<body>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
<script>
const ws = new WebSocket('ws://localhost:9090/testWs');
ws.onopen = function(event) {
console.log('连接已建立');
};
ws.onmessage = function(event) {
const messages = document.getElementById('messages');
messages.innerHTML += '<p>' + event.data + '</p>';
};
function sendMessage() {
const input = document.getElementById('messageInput');
ws.send(input.value);
input.value = '';
}
</script>
</body>
</html>
3.2 消息处理逻辑
java
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
Channel channel = ctx.channel();
log.info("收到来自通道channelId[{}]发送的消息:{}", channel.id(), msg.text());
// 回复确认消息给发送者
ctx.writeAndFlush(new TextWebSocketFrame("收到您的消息:" + msg.text()));
// 广播消息给其他所有客户端(注释部分)
// channelGroup.writeAndFlush(new TextWebSocketFrame("来自[" + channel.id() + "]的消息:" + msg.text()));
}
四、功能特性说明
4.1 连接管理
- 连接建立 :通过
handlerAdded()捕获新连接并添加到ChannelGroup - 连接断开 :通过
handlerRemoved()清理断开的连接 - 连接监控:记录连接状态变化日志
4.2 消息处理
- 单播:只回复给发送消息的客户端
- 广播:可以向所有连接的客户端发送消息(需取消注释相关代码)
4.3 错误处理
- 异常捕获:在
init()方法中捕获InterruptedException - 日志记录:详细记录连接状态和消息处理过程
五、部署与测试
5.1 启动服务
- Spring Boot应用启动后会自动初始化WebSocket服务器
- 服务器监听端口:
9090 - WebSocket路径:
/testWs
5.2 测试验证
- 打开多个浏览器窗口访问客户端页面
- 在任意窗口发送消息
- 观察其他窗口是否能收到对应消息
- 查看控制台日志验证连接状态
六、优化建议
6.1 性能优化
- 根据服务器性能调整
NioEventLoopGroup线程数 - 合理设置消息聚合器大小
- 实现心跳机制防止连接超时
6.2 安全考虑
- 添加身份验证机制
- 实现消息过滤和防攻击机制
- 考虑使用WSS(WebSocket Secure)协议
这个WebSocket服务器为实时通信提供了坚实的基础架构,可根据具体业务需求进行定制化开发。
java
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* WebSocket服务器类
*/
@Getter
@Slf4j
@Component
public class WebSocketServer {
// 管理所有WebSocket连接的通道组
private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@PostConstruct
public void init() {
new Thread(() -> {
try {
start();
} catch (InterruptedException e) {
log.error("启动WebSocket服务器失败!", e);
}
}).start();
}
/**
* 启动WebSocket服务器
*/
public void start() throws InterruptedException {
// 主线程组:处理客户端连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
// 工作线程组:处理连接后的I/O操作
EventLoopGroup workGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
ChannelPipeline pipeline = socketChannel.pipeline();
// HTTP编解码器
pipeline.addLast(new HttpServerCodec());
// HTTP消息聚合器
pipeline.addLast(new HttpObjectAggregator(65535));
// WebSocket协议处理器,路径为/testWs
pipeline.addLast(new WebSocketServerProtocolHandler("/testWs"));
// 自定义业务处理器
pipeline.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
// 客户端连接建立
Channel channel = ctx.channel();
log.info("客户端 建立连接:channelId={}", channel.id());
channelGroup.add(channel);
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
// 客户端连接断开
Channel channel = ctx.channel();
log.info("客户端 断开连接:channelId={}", channel.id());
channelGroup.remove(channel);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
// 处理收到的文本消息
Channel channel = ctx.channel();
log.info("收到来自通道channelId[{}]发送的消息:{}", channel.id(), msg.text());
// 回复消息给发送者
ctx.writeAndFlush(new TextWebSocketFrame("收到您的消息:" + msg.text()));
// 广播消息给所有客户端
//channelGroup.writeAndFlush( new TextWebSocketFrame("收到来自通道channelId[" + channel.id() + "]发送的消息:" + msg.text()));
}
});
}
});
// 绑定端口并启动服务器
ChannelFuture channelFuture = serverBootstrap.bind(9090).sync();
log.info("Server started and listen on:{}", channelFuture.channel().localAddress());
// 等待服务器关闭
channelFuture.channel().closeFuture().sync();
}
}
客户端连接地址 ws://127.0.0.1:9090/testWs
6.3 调试
推荐一个WebSocke在线网站
https://webfem.com/tools/ws/index.html
七、总结
基于Netty框架构建的WebSocket服务器,实现了完整的实时通信功能。
核心技术 :采用Netty的NioEventLoopGroup线程模型,通过ChannelGroup管理连接池
协议处理 :配置HTTP编解码器和WebSocket协议处理器,路径为/testWs
功能特性 :支持连接建立/断开监控、单播回复和广播消息、详细日志记录
部署运行:自动随Spring Boot启动,监听端口9090,适用于聊天室、消息推送等实时交互场景