Demo netty 2

This commit is contained in:
MartyJ28 2024-10-27 20:35:34 +08:00
parent 100656c611
commit 63c5024bea
4 changed files with 117 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package com.example.demo; package com.example.demo;
import com.example.demo.Entity.Person; import com.example.demo.Entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@ -9,13 +10,12 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication @SpringBootApplication
@EnableScheduling //开启定时任务 @EnableScheduling //开启定时任务
public class DemoApplication { public class DemoApplication {
public static void main(String[] args) { public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
System.out.println(run.getBeanDefinitionCount()); System.out.println(run.getBeanDefinitionCount());
System.out.println();
} }
} }

View File

@ -0,0 +1,64 @@
package com.example.demo.Service;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
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.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class WebSocketServer {
@Value("${netty.port}")
private int port;
private final WebSocketServerHandler webSocketServerHandler;
public WebSocketServer(WebSocketServerHandler webSocketServerHandler) {
this.webSocketServerHandler = webSocketServerHandler;
}
@PostConstruct
public void start() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new ChunkedWriteHandler());
ch.pipeline().addLast(new HttpObjectAggregator(8192));
// WebSocket协议处理器
ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws"));
ch.pipeline().addLast(new WebSocketServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
System.out.println("WebSocket Server started on port: " + port);
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

View File

@ -0,0 +1,48 @@
package com.example.demo.Service;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.stereotype.Component;
@Component
public class WebSocketServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
// 管理所有连接的WebSocket通道
private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private WebSocketServerHandshaker webSocketServerHandshaker;
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
channels.add(ctx.channel());
channels.writeAndFlush(new TextWebSocketFrame("[客户端] - " + ctx.channel().remoteAddress() + " 加入聊天室"));
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
channels.remove(ctx.channel());
channels.writeAndFlush(new TextWebSocketFrame("[客户端] - " + ctx.channel().remoteAddress() + " 离开聊天室"));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
// 广播消息到所有客户端
channels.forEach(ch -> {
if (ch != ctx.channel()) {
ch.writeAndFlush(new TextWebSocketFrame("[客户端] " + ctx.channel().remoteAddress() + " 说:" + msg.text()));
} else {
ch.writeAndFlush(new TextWebSocketFrame("[你] 说:" + msg.text()));
}
});
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View File

@ -14,3 +14,5 @@ spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
#??mapper xml??? #??mapper xml???
mybatis-plus.mapper-locations=classpath:mappers/*.xml mybatis-plus.mapper-locations=classpath:mappers/*.xml
netty.port=8080