概述
我们将创建一个基于Netty的服务器,用于管理用户的在线状态。服务器将能够处理用户的登录和登出请求,并通过WebSocket协议实时通知客户端有关用户在线状态的变化。通过Spring Boot管理Netty的启动和停止,以及统计在线用户的数量。
详细实现
1. 创建Spring Boot项目
首先,创建一个空的Spring Boot项目,确保在项目的pom.xml
文件中添加Netty的依赖。
<!-- pom.xml -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.66.Final</version> <!-- 检查最新版本 -->
</dependency>
2. 编写Netty服务器
创建一个Netty服务器类,处理用户登录、登出和状态统计。
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
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.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.stereotype.Component;
@Component
public class NettyServer {
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
public void start(int port) throws InterruptedException {
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new WebSocketHandler()); // 自定义处理器,处理WebSocket请求
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public void stop() {
if (bossGroup != null) {
bossGroup.shutdownGracefully();
}
if (workerGroup != null) {
workerGroup.shutdownGracefully();
}
}
}
3. 自定义WebSocket处理器
编写处理WebSocket请求的自定义处理器,实现用户登录、登出功能,同时更新在线用户状态。
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.*;
public class WebSocketHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
// 处理WebSocket连接建立
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
// 处理WebSocket连接建立逻辑,比如记录用户登录信息等
}
super.userEventTriggered(ctx, evt);
}
// 处理WebSocket帧消息
@Override
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
if (msg instanceof CloseWebSocketFrame) {
// 处理WebSocket关闭逻辑,用户登出
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 异常处理逻辑
super.exceptionCaught(ctx, cause);
}
}
4. Spring Boot集成和控制器
创建一个Spring Boot控制器,用于启动和停止Netty服务器,并提供统计在线用户数量的接口。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/admin")
public class AdminController {
@Autowired
private NettyServer nettyServer;
@PostMapping("/start")
public String startServer(@RequestParam int port) {
try {
nettyServer.start(port);
return "Netty server started on port " + port;
} catch (InterruptedException e) {
return "Failed to start Netty server";
}
}
@PostMapping("/stop")
public String stopServer() {
nettyServer.stop();
return "Netty server stopped";
}
@GetMapping("/onlineUsers")
public int getOnlineUsersCount() {
// 实现在线用户统计逻辑,可以从WebSocketHandler中获取在线用户数量
return 0; // 示例:返回在线用户数量
}
}
5. WebSocket客户端实现
在前端或其他客户端应用中,实现WebSocket连接,监听在线状态的变化,并根据需要显示或处理在线用户的状态信息。