From f393cc6b070d88a43caaccd884b0bd28c26cf767 Mon Sep 17 00:00:00 2001 From: zhangmeng <1334717033@qq.com> Date: Fri, 3 Mar 2023 18:07:16 +0800 Subject: [PATCH] =?UTF-8?q?2023=E5=B9=B43=E6=9C=883=E6=97=A518:06:51?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + .../tools/JavaFxToolsApplication.java | 1 - .../controller/NettyClientController.java | 156 +++++++++--------- .../com/zhangmeng/tools/netty/Function.java | 14 -- .../com/zhangmeng/tools/netty/Message.java | 23 --- .../zhangmeng/tools/netty/NettyClient.java | 138 ---------------- .../zhangmeng/tools/netty/ResponseJson.java | 84 ---------- .../tools/netty/WebsocketClientHandler.java | 81 --------- .../zhangmeng/tools/utils/Multithreading.java | 58 ------- src/main/resources/fxml/netty-client.fxml | 20 +-- 10 files changed, 87 insertions(+), 494 deletions(-) delete mode 100644 src/main/java/com/zhangmeng/tools/netty/Function.java delete mode 100644 src/main/java/com/zhangmeng/tools/netty/Message.java delete mode 100644 src/main/java/com/zhangmeng/tools/netty/NettyClient.java delete mode 100644 src/main/java/com/zhangmeng/tools/netty/ResponseJson.java delete mode 100644 src/main/java/com/zhangmeng/tools/netty/WebsocketClientHandler.java delete mode 100644 src/main/java/com/zhangmeng/tools/utils/Multithreading.java diff --git a/pom.xml b/pom.xml index a79dd7e..b97b503 100644 --- a/pom.xml +++ b/pom.xml @@ -555,6 +555,12 @@ org.projectlombok lombok + + + org.java-websocket + Java-WebSocket + 1.3.5 + diff --git a/src/main/java/com/zhangmeng/tools/JavaFxToolsApplication.java b/src/main/java/com/zhangmeng/tools/JavaFxToolsApplication.java index bc5e563..05cd30a 100644 --- a/src/main/java/com/zhangmeng/tools/JavaFxToolsApplication.java +++ b/src/main/java/com/zhangmeng/tools/JavaFxToolsApplication.java @@ -27,7 +27,6 @@ package com.zhangmeng.tools; import com.zhangmeng.tools.views.HomeView; import javafx.application.Application; -import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** diff --git a/src/main/java/com/zhangmeng/tools/controller/NettyClientController.java b/src/main/java/com/zhangmeng/tools/controller/NettyClientController.java index c927034..84929d3 100644 --- a/src/main/java/com/zhangmeng/tools/controller/NettyClientController.java +++ b/src/main/java/com/zhangmeng/tools/controller/NettyClientController.java @@ -1,6 +1,5 @@ package com.zhangmeng.tools.controller; -import com.zhangmeng.tools.netty.NettyClient; import com.zhangmeng.tools.utils.AlertUtils; import javafx.application.Platform; import javafx.collections.FXCollections; @@ -10,11 +9,17 @@ import javafx.fxml.FXML; import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.layout.HBox; +import javafx.scene.paint.Color; import javafx.util.Callback; import javafx.util.StringConverter; import lombok.extern.slf4j.Slf4j; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.handshake.ServerHandshake; +import java.net.URI; + /** * @author : 芊芊墨客 @@ -27,34 +32,22 @@ public class NettyClientController { @FXML private Button send; - @FXML - private TextField key; - - @FXML - private TextField value; - @FXML private TextField url_address; @FXML private TextField port; - @FXML - private ListView param_list; - @FXML private TextArea result_show; - @FXML - private Button add; - @FXML private Button connect; @FXML private TextArea send_msg; - private NettyClient nettyClient; + private WebSocketClient webSocketClient; /** * 本客户端后台是否已启动 @@ -120,43 +113,6 @@ public class NettyClientController { } }); - param_list.setPlaceholder(new Label("没有数据")); - param_list.setEditable(true); - param_list.setCellFactory(new Callback<>() { - @Override - public ListCell call(ListView param) { - return new ListCell<>(){ - @Override - protected void updateItem(Data data, boolean b) { - super.updateItem(data, b); - if (!b){ - HBox hbox = new HBox(); - hbox.setAlignment(Pos.CENTER); - hbox.getChildren().add(new Label(data.getKey() + "---" + data.getValue())); - this.setGraphic(hbox); - } - } - }; - } - }); - param_list.setItems(list); - - add.setOnAction(event -> { - - if (key.getText().length() == 0){ - AlertUtils.alert_warning("key不能为空!"); - return; - } - if (value.getText().length() == 0){ - AlertUtils.alert_warning("value不能为空!"); - return; - } - list.add(new Data(key.getText(),value.getText())); - - key.setText(null); - value.setText(null); - }); - if (port.getText().length() == 0) { port.setText(String.valueOf(socket_port)); } @@ -165,42 +121,23 @@ public class NettyClientController { url_address.setText(socket_address); } + connect.setOnAction(event -> { + getConnection(); + }); + send.setOnAction(event -> { if (send_msg.getText().length() == 0){ AlertUtils.alert_warning("请输入内容再试!"); } - String msg = send_msg.getText(); -// Multithreading.execute(() -> { -// if (nettyClient == null){ -// this.nettyClient = NettyClient.getInstance(); -// this.nettyClient.setPort(socket_port); -// this.nettyClient.setIp(socket_address); -// StringBuilder params = new StringBuilder(); -// for (Data data : list) { -// if (params.toString().equals("")){ -// params.append(data.key).append("=").append(data.value); -// }else { -// params.append("&").append(data.key).append("=").append(data.value); -// } -// } -// this.nettyClient.setParams(params.toString()); -// log.info("params:{}",params.toString()); -// } -// -// // 让客户端后台懒启动。避免先于服务端启动而引发异常 -// if (!isStarted) { -// this.nettyClient.start(); -// isStarted = true; -// } -// -// Platform.runLater(() -> { -// this.nettyClient.send(msg); -// }); -// add_message(msg); -// }); + if (webSocketClient == null){ + AlertUtils.alert_warning("请先连接websocket服务器再试!"); + return; + } + + webSocketClient.send(msg); add_message(msg); this.send_msg.requestFocus(); @@ -208,6 +145,65 @@ public class NettyClientController { }); } + private void getConnection(){ + if (webSocketClient == null) { + webSocketClient(Type.ws, url_address.getText(), Integer.parseInt(port.getText()), "/websocket", "userId=1&source=pc"); + } + } + + public enum Type{ + ws("ws"), + wss("wss") + ; + + Type(String name) { + this.name = name; + } + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public void webSocketClient(Type type,String socket_address,int socket_port,String path ,String params) { + try { + webSocketClient = new WebSocketClient(new URI(type.name + "://" + socket_address + ":" + socket_port + path + "?" + params), new Draft_6455()) { + //连接服务端时触发 + @Override + public void onOpen(ServerHandshake handshakedata) { + log.info("websocket客户端和服务器连接成功"); + add_message("websocket客户端和服务器连接成功!"); + } + //收到服务端消息时触发 + @Override + public void onMessage(String message) { + log.info("websocket客户端收到消息={}", message); + add_message("websocket客户端收到消息={" + message + "}"); + } + //和服务端断开连接时触发 + @Override + public void onClose(int code, String reason, boolean remote) { + log.info("websocket客户端退出连接"); + add_message("websocket客户端退出连接"); + } + //连接异常时触发 + @Override + public void onError(Exception ex) { + log.info("websocket客户端和服务器连接发生错误={}", ex.getMessage()); + add_message("websocket客户端和服务器连接发生错误={" + ex.getMessage() + "}"); + } + }; + webSocketClient.connect(); + } catch (Exception e) { + e.printStackTrace(); + } + } public void receive(String msg) { Platform.runLater(() -> { diff --git a/src/main/java/com/zhangmeng/tools/netty/Function.java b/src/main/java/com/zhangmeng/tools/netty/Function.java deleted file mode 100644 index 9054df7..0000000 --- a/src/main/java/com/zhangmeng/tools/netty/Function.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.zhangmeng.tools.netty; - -/** - * @author : 芊芊墨客 - * @version : 1.0 - * @date : 2023-02-27 10:02 - */ -@FunctionalInterface -public interface Function { - /** - * @since 2021-10-3 - */ - void run(); -} diff --git a/src/main/java/com/zhangmeng/tools/netty/Message.java b/src/main/java/com/zhangmeng/tools/netty/Message.java deleted file mode 100644 index 49b2771..0000000 --- a/src/main/java/com/zhangmeng/tools/netty/Message.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.zhangmeng.tools.netty; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author : 芊芊墨客 - * @version : 1.0 - * @date : 2023-02-27 11:22 - */ -public class Message { - - public static List message_result_list = new ArrayList<>(); - - public static void clear_message(){ - Message.message_result_list.clear(); - } - - public static void add(String msg){ - Message.message_result_list.add(msg); - Message.message_result_list.add(System.lineSeparator()); - } -} diff --git a/src/main/java/com/zhangmeng/tools/netty/NettyClient.java b/src/main/java/com/zhangmeng/tools/netty/NettyClient.java deleted file mode 100644 index 7c8b5ff..0000000 --- a/src/main/java/com/zhangmeng/tools/netty/NettyClient.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.zhangmeng.tools.netty; - -import io.netty.bootstrap.Bootstrap; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.channel.*; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.codec.http.*; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; -import io.netty.handler.codec.http.websocketx.WebSocketVersion; -import io.netty.handler.stream.ChunkedWriteHandler; -import lombok.extern.slf4j.Slf4j; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * @author : 芊芊墨客 - * @version : 1.0 - * @date : 2023-02-27 09:15 - */ -@Slf4j -public class NettyClient { - - public enum Type { - Ws("ws"), Wss("wss"); - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - Type(String name) { - this.name = name; - } - } - - private String serverIp; - - private int serverPort; - - private String params; - - private Channel channel = null; - - private EventLoopGroup workerLoopGroup = null; - private ChannelFuture future = null; - - public void start() { - workerLoopGroup = new NioEventLoopGroup(); - Bootstrap bootstrap = new Bootstrap(); - bootstrap.group(workerLoopGroup); - bootstrap.channel(NioSocketChannel.class); - bootstrap.remoteAddress(serverIp, serverPort); - bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); - bootstrap.handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel ch) { - // HTTP编码解码器 - ch.pipeline().addLast("http-codec", new HttpServerCodec()); - // 把HTTP头、HTTP体拼成完整的HTTP请求 - ch.pipeline().addLast("aggregator", new HttpObjectAggregator(65536)); - // 方便大文件传输,不过实质上都是短的文本数据 - ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); - // 定义业务处理器 - ch.pipeline().addLast("businessHandler", new WebsocketClientHandler()); - } - }); - - - try { - URI websocketURI = new URI(String.format("ws://%s:%d/websocket?%s", serverIp, serverPort,params)); - log.info(String.format("ws://%s:%d/", serverIp, serverPort)); - HttpHeaders httpHeaders = new DefaultHttpHeaders(); - //进行握手 - WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, (String)null, true,httpHeaders); - channel = bootstrap.connect(websocketURI.getHost(), websocketURI.getPort()).sync().channel(); - WebsocketClientHandler handler = (WebsocketClientHandler)channel.pipeline().get("businessHandler"); - handler.setHandshaker(handshaker); - // 通过它构造握手响应消息返回给客户端, - // 同时将WebSocket相关的编码和解码类动态添加到ChannelPipeline中,用于WebSocket消息的编解码, - // 添加WebSocketEncoder和WebSocketDecoder之后,服务端就可以自动对WebSocket消息进行编解码了 - handshaker.handshake(channel); - //阻塞等待是否握手成功 - future = handler.handshakeFuture().sync(); - - future.addListener((ChannelFuture futureListener) -> { - if (futureListener.isSuccess()) { - log.info("客户端连接成功"); - } else { - log.info("客户端连接失败"); - } - }); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - - public void send(String msg) { - channel.writeAndFlush(new TextWebSocketFrame(msg)); - } - - public void destroy() { - this.workerLoopGroup.shutdownGracefully(); - } - - private NettyClient() { - super(); - } - - public static NettyClient getInstance() { - return new NettyClient(); - } - - public NettyClient setIp(String serverIp) { - this.serverIp = serverIp; - return this; - } - - public NettyClient setPort(int serverPort) { - this.serverPort = serverPort; - return this; - } - - public NettyClient setParams(String params) { - this.params = params; - return this; - } -} diff --git a/src/main/java/com/zhangmeng/tools/netty/ResponseJson.java b/src/main/java/com/zhangmeng/tools/netty/ResponseJson.java deleted file mode 100644 index 4b9e8b6..0000000 --- a/src/main/java/com/zhangmeng/tools/netty/ResponseJson.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.zhangmeng.tools.netty; - -import com.alibaba.fastjson.JSONObject; -import org.springframework.http.HttpStatus; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -public class ResponseJson extends HashMap { - private static final long serialVersionUID = 1L; - - private static final Integer SUCCESS_STATUS = 200; - private static final Integer ERROR_STATUS = -1; - private static final String SUCCESS_MSG = "一切正常"; - - public ResponseJson() { - super(); - } - - public ResponseJson(int code) { - super(); - setStatus(code); - } - - public ResponseJson(HttpStatus status) { - super(); - setStatus(status.value()); - setMsg(status.getReasonPhrase()); - } - - public ResponseJson success() { - put("msg", SUCCESS_MSG); - put("status", SUCCESS_STATUS); - return this; - } - - public ResponseJson success(String msg) { - put("msg", msg); - put("status", SUCCESS_STATUS); - return this; - } - - public ResponseJson error(String msg) { - put("msg", msg); - put("status", ERROR_STATUS); - return this; - } - - public ResponseJson setData(String key, Object obj) { - @SuppressWarnings("unchecked") - HashMap data = (HashMap) get("data"); - if (data == null) { - data = new HashMap(); - put("data", data); - } - data.put(key, obj); - return this; - } - - public ResponseJson setStatus(int status) { - put("status", status); - return this; - } - - public ResponseJson setMsg(String msg) { - put("msg", msg); - return this; - } - - public ResponseJson setValue(String key, Object val) { - put(key, val); - return this; - } - - /** - * 返回JSON字符串 - */ - @Override - public String toString() { - return JSONObject.toJSONString(this); - } -} diff --git a/src/main/java/com/zhangmeng/tools/netty/WebsocketClientHandler.java b/src/main/java/com/zhangmeng/tools/netty/WebsocketClientHandler.java deleted file mode 100644 index 758f4d5..0000000 --- a/src/main/java/com/zhangmeng/tools/netty/WebsocketClientHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.zhangmeng.tools.netty; - -import com.zhangmeng.tools.controller.NettyClientController; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.*; -import io.netty.handler.codec.http.*; -import io.netty.handler.codec.http.websocketx.*; -import io.netty.util.CharsetUtil; -import io.netty.util.concurrent.Future; -import lombok.extern.slf4j.Slf4j; - -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.Map; - -/** - * @author : 芊芊墨客 - * @version : 1.0 - * @date : 2023-02-27 09:20 - */ -@Slf4j -public class WebsocketClientHandler extends SimpleChannelInboundHandler { - - WebSocketClientHandshaker handshaker; - ChannelPromise handshakeFuture; - - public void handlerAdded(ChannelHandlerContext ctx) { - this.handshakeFuture = ctx.newPromise(); - } - public WebSocketClientHandshaker getHandshaker() { - return handshaker; - } - - public void setHandshaker(WebSocketClientHandshaker handshaker) { - this.handshaker = handshaker; - } - - public ChannelPromise getHandshakeFuture() { - return handshakeFuture; - } - - public void setHandshakeFuture(ChannelPromise handshakeFuture) { - this.handshakeFuture = handshakeFuture; - } - - public ChannelFuture handshakeFuture() { - return this.handshakeFuture; - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { - // 关闭请求 - if (frame instanceof CloseWebSocketFrame) { - if (handshaker == null) { - sendErrorMessage(ctx, "不存在的客户端连接!"); - } else { - 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)) { - sendErrorMessage(ctx, "仅支持文本(Text)格式,不支持二进制消息"); - } - String request = ((TextWebSocketFrame) frame).text(); - log.info(request); - } - - private void sendErrorMessage(ChannelHandlerContext ctx, String errorMsg) { - String responseJson = new ResponseJson() - .error(errorMsg) - .toString(); - ctx.channel().writeAndFlush(new TextWebSocketFrame(responseJson)); - } -} \ No newline at end of file diff --git a/src/main/java/com/zhangmeng/tools/utils/Multithreading.java b/src/main/java/com/zhangmeng/tools/utils/Multithreading.java deleted file mode 100644 index eff0284..0000000 --- a/src/main/java/com/zhangmeng/tools/utils/Multithreading.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.zhangmeng.tools.utils; - -import java.util.concurrent.Future; - -import com.zhangmeng.tools.netty.Function; -import javafx.concurrent.Task; - - -/** - * @author : 芊芊墨客 - * @version : 1.0 - * @date : 2023-02-27 10:00 - */ -public class Multithreading { - - /** - * 无结果反馈的版本 - * - * @since 2021-10-3 - * @lastModified 2021-10-10 - */ - public static void execute(Function function) { - /** - * 开新线程来完成下面的操作 - */ - Task task = new Task<>() { - @Override - protected Integer call() { - function.run(); - return null; // 因为此处不需要结果反馈,所以返回 null - } - }; - ExecutorUtils.getTasks().add(task); - ExecutorUtils.getExecutor().execute(task); - } - - /** - * 有结果反馈的版本 - * - * @since 2021-10-10 - */ - public static Future submit(Function function) { - - /** - * 开新线程来完成下面的操作 - */ - Task task = new Task<>() { - @Override - protected Object call() { - function.run(); - return null; // 因为此处暂时没定好应该反馈什么东西,所以返回 null - } - }; - ExecutorUtils.getTasks().add(task); - return ExecutorUtils.getExecutor().submit(task); - } - -} diff --git a/src/main/resources/fxml/netty-client.fxml b/src/main/resources/fxml/netty-client.fxml index 210e1b9..558b198 100644 --- a/src/main/resources/fxml/netty-client.fxml +++ b/src/main/resources/fxml/netty-client.fxml @@ -2,29 +2,19 @@ - - -