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