From ba0f00cf00c2a5c693e9608a56d1f7d032f5e216 Mon Sep 17 00:00:00 2001
From: zengh <123456>
Date: Tue, 23 Mar 2021 19:19:17 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/webscoket/WebSocketHandler.java | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/webscoket/WebSocketHandler.java b/blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/webscoket/WebSocketHandler.java
new file mode 100644
index 0000000..42794ea
--- /dev/null
+++ b/blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/webscoket/WebSocketHandler.java
@@ -0,0 +1,161 @@
+package org.springblade.jfpt.webscoket;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.*;
+import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import io.netty.handler.codec.http.HttpVersion;
+import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketFrame;
+import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
+import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
+import io.netty.util.CharsetUtil;
+import java.util.Date;
+
+import org.springblade.jfpt.suser.service.ISuserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+@Component
+public class WebSocketHandler extends SimpleChannelInboundHandler<Object> {
+
+ private WebSocketServerHandshaker handshaker;
+
+ private String on=null;
+
+ @Autowired
+ private ISuserService suserService;
+
+ private static WebSocketHandler webSocketHandler;
+
+ @PostConstruct
+ public void init() {
+ webSocketHandler = this;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
+ if (msg instanceof FullHttpRequest) {
+ //以http请求形式接入,但是走的是websocket
+ handleHttpRequest(ctx, (FullHttpRequest) msg);
+ } else if (msg instanceof WebSocketFrame) {
+ //处理websocket客户端的消息
+ handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
+ }
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ //添加连接
+ System.out.println("客户端加入连接:" + ctx.channel());
+ //ChannelSupervise.addChannel(ctx.channel());
+ }
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ //断开连接
+ System.out.println("客户端断开连接:" + ctx.channel());
+ //用户离线状态
+ String name = ChannelSupervise.findName(ctx.channel().id().asShortText());
+ String num="0";
+ webSocketHandler.suserService.updateUser(num,name);
+ ChannelSupervise.removeChannel(ctx.channel());
+ }
+
+ @Override
+ public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+ ctx.flush();
+ }
+
+ private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) throws NumberFormatException, Exception {
+ // 判断是否关闭链路的指令
+ if (frame instanceof CloseWebSocketFrame) {
+ handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
+ return;
+ }
+ // 判断是否ping消息
+ if (frame instanceof PingWebSocketFrame) {
+ ctx.channel().write(
+ new PongWebSocketFrame(frame.content().retain()));
+ return;
+ }
+ // 本例程仅支持文本消息,不支持二进制消息
+ if (!(frame instanceof TextWebSocketFrame)) {
+ System.out.println("本例程仅支持文本消息,不支持二进制消息");
+ throw new UnsupportedOperationException(String.format(
+ "%s frame types not supported", frame.getClass().getName()));
+ }
+ // 返回应答消息
+ String request = ((TextWebSocketFrame) frame).text();
+ //把用户信息添加到通道里
+ ChannelSupervise.addChannel(ctx.channel(),request);
+ //用户在线状态
+ this.on=request;
+ String num="1";
+ webSocketHandler.suserService.updateUser(num,request);
+ TextWebSocketFrame tws = new TextWebSocketFrame(new Date().toString()
+ + ctx.channel().id() + ":" + ctx.channel());
+ // 返回【谁发的发给谁】
+
+ ctx.channel().writeAndFlush(tws);
+ // 群发
+ // ChannelSupervise.send2All(tws);
+ }
+
+ /**
+ * 唯一的一次http请求,用于创建websocket
+ *
+ * @throws InterruptedException
+ */
+ private void handleHttpRequest(final ChannelHandlerContext ctx,
+ FullHttpRequest req) throws InterruptedException {
+ //要求Upgrade为websocket,过滤掉get/Post
+ if (!req.decoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
+ //若不是websocket方式,则创建BAD_REQUEST的req,返回给客户端
+ sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
+ return;
+ }
+ //握手
+ WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
+ "ws://localhost:9034/websocket", null, false);
+ handshaker = wsFactory.newHandshaker(req);
+ if (handshaker == null) {
+ WebSocketServerHandshakerFactory
+ .sendUnsupportedVersionResponse(ctx.channel());
+ } else {
+ handshaker.handshake(ctx.channel(), req);
+ }
+ }
+
+ /**
+ * 拒绝不合法的请求,并返回错误信息
+ */
+ private static void sendHttpResponse(ChannelHandlerContext ctx,
+ FullHttpRequest req, DefaultFullHttpResponse res) {
+ // 返回应答给客户端
+ if (res.status().code() != 200) {
+ ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(),
+ CharsetUtil.UTF_8);
+ res.content().writeBytes(buf);
+ buf.release();
+ }
+ ChannelFuture f = ctx.channel().writeAndFlush(res);
+ // 如果是非Keep-Alive,关闭连接
+// if (!isKeepAlive(req) || res.status().code() != 200) {
+// f.addListener(ChannelFutureListener.CLOSE);
+// }
+ }
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ cause.printStackTrace();
+ ctx.close();
+ }
+
+}
--
Gitblit v1.9.3