2023年3月3日18:06:51
parent
0f12ae23df
commit
f393cc6b07
6
pom.xml
6
pom.xml
|
|
@ -555,6 +555,12 @@
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.java-websocket</groupId>
|
||||||
|
<artifactId>Java-WebSocket</artifactId>
|
||||||
|
<version>1.3.5</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ package com.zhangmeng.tools;
|
||||||
|
|
||||||
import com.zhangmeng.tools.views.HomeView;
|
import com.zhangmeng.tools.views.HomeView;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.zhangmeng.tools.controller;
|
package com.zhangmeng.tools.controller;
|
||||||
|
|
||||||
import com.zhangmeng.tools.netty.NettyClient;
|
|
||||||
import com.zhangmeng.tools.utils.AlertUtils;
|
import com.zhangmeng.tools.utils.AlertUtils;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
|
|
@ -10,11 +9,17 @@ import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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 : 芊芊墨客
|
* @author : 芊芊墨客
|
||||||
|
|
@ -27,34 +32,22 @@ public class NettyClientController {
|
||||||
@FXML
|
@FXML
|
||||||
private Button send;
|
private Button send;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private TextField key;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private TextField value;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TextField url_address;
|
private TextField url_address;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TextField port;
|
private TextField port;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ListView<Data> param_list;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TextArea result_show;
|
private TextArea result_show;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Button add;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button connect;
|
private Button connect;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TextArea send_msg;
|
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<Data> call(ListView<Data> 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) {
|
if (port.getText().length() == 0) {
|
||||||
port.setText(String.valueOf(socket_port));
|
port.setText(String.valueOf(socket_port));
|
||||||
}
|
}
|
||||||
|
|
@ -165,42 +121,23 @@ public class NettyClientController {
|
||||||
url_address.setText(socket_address);
|
url_address.setText(socket_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect.setOnAction(event -> {
|
||||||
|
getConnection();
|
||||||
|
});
|
||||||
|
|
||||||
send.setOnAction(event -> {
|
send.setOnAction(event -> {
|
||||||
|
|
||||||
if (send_msg.getText().length() == 0){
|
if (send_msg.getText().length() == 0){
|
||||||
AlertUtils.alert_warning("请输入内容再试!");
|
AlertUtils.alert_warning("请输入内容再试!");
|
||||||
}
|
}
|
||||||
|
|
||||||
String msg = send_msg.getText();
|
String msg = send_msg.getText();
|
||||||
|
|
||||||
// Multithreading.execute(() -> {
|
if (webSocketClient == null){
|
||||||
// if (nettyClient == null){
|
AlertUtils.alert_warning("请先连接websocket服务器再试!");
|
||||||
// this.nettyClient = NettyClient.getInstance();
|
return;
|
||||||
// this.nettyClient.setPort(socket_port);
|
}
|
||||||
// this.nettyClient.setIp(socket_address);
|
|
||||||
// StringBuilder params = new StringBuilder();
|
webSocketClient.send(msg);
|
||||||
// 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);
|
|
||||||
// });
|
|
||||||
add_message(msg);
|
add_message(msg);
|
||||||
|
|
||||||
this.send_msg.requestFocus();
|
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) {
|
public void receive(String msg) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
@ -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<String> 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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<SocketChannel>() {
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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<String, Object> {
|
|
||||||
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<String, Object> data = (HashMap<String, Object>) get("data");
|
|
||||||
if (data == null) {
|
|
||||||
data = new HashMap<String, Object>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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<WebSocketFrame> {
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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<Object> 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<Object> task = new Task<>() {
|
|
||||||
@Override
|
|
||||||
protected Object call() {
|
|
||||||
function.run();
|
|
||||||
return null; // 因为此处暂时没定好应该反馈什么东西,所以返回 null
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ExecutorUtils.getTasks().add(task);
|
|
||||||
return ExecutorUtils.getExecutor().submit(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -2,29 +2,19 @@
|
||||||
|
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.ListView?>
|
|
||||||
<?import javafx.scene.control.TextArea?>
|
<?import javafx.scene.control.TextArea?>
|
||||||
<?import javafx.scene.control.TextField?>
|
<?import javafx.scene.control.TextField?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
<?import javafx.scene.text.Text?>
|
|
||||||
|
|
||||||
<AnchorPane prefHeight="649.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zhangmeng.tools.controller.NettyClientController">
|
<AnchorPane prefHeight="649.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zhangmeng.tools.controller.NettyClientController">
|
||||||
<children>
|
<children>
|
||||||
<Label layoutX="98.0" layoutY="49.0" text="链接地址:" AnchorPane.topAnchor="49.0" />
|
<Label layoutX="98.0" layoutY="141.0" text="链接地址:" AnchorPane.topAnchor="141.0" />
|
||||||
<TextField fx:id="url_address" layoutX="169.0" layoutY="45.0" prefHeight="25.0" prefWidth="431.0" />
|
<TextField fx:id="url_address" layoutX="169.0" layoutY="137.0" prefHeight="25.0" prefWidth="431.0" />
|
||||||
<Label layoutX="626.0" layoutY="49.0" text="端口:" />
|
<Label layoutX="626.0" layoutY="141.0" text="端口:" />
|
||||||
<TextField fx:id="port" layoutX="662.0" layoutY="45.0" />
|
<TextField fx:id="port" layoutX="662.0" layoutY="137.0" />
|
||||||
<Label layoutX="98.0" layoutY="94.0" text="参数:" />
|
|
||||||
<TextField fx:id="key" layoutX="169.0" layoutY="90.0" />
|
|
||||||
<Text layoutX="343.0" layoutY="107.0" strokeType="OUTSIDE" strokeWidth="0.0" text="(key)" />
|
|
||||||
<TextField fx:id="value" layoutX="410.0" layoutY="90.0" />
|
|
||||||
<Text layoutX="588.0" layoutY="107.0" strokeType="OUTSIDE" strokeWidth="0.0" text="(value)" />
|
|
||||||
<Label layoutX="798.0" layoutY="94.0" text="参数列表:" />
|
|
||||||
<ListView fx:id="param_list" layoutX="888.0" layoutY="44.0" prefHeight="200.0" prefWidth="241.0" AnchorPane.leftAnchor="888.0" AnchorPane.rightAnchor="71.0" AnchorPane.topAnchor="45.0" />
|
|
||||||
<TextArea fx:id="send_msg" layoutX="98.0" layoutY="255.0" prefHeight="114.0" prefWidth="1031.0" AnchorPane.bottomAnchor="280.0" AnchorPane.leftAnchor="98.0" AnchorPane.rightAnchor="71.0" AnchorPane.topAnchor="255.0" />
|
<TextArea fx:id="send_msg" layoutX="98.0" layoutY="255.0" prefHeight="114.0" prefWidth="1031.0" AnchorPane.bottomAnchor="280.0" AnchorPane.leftAnchor="98.0" AnchorPane.rightAnchor="71.0" AnchorPane.topAnchor="255.0" />
|
||||||
<Button fx:id="send" layoutX="653.0" layoutY="379.0" mnemonicParsing="false" text="发送" AnchorPane.bottomAnchor="245.0" AnchorPane.leftAnchor="653.0" />
|
<Button fx:id="send" layoutX="653.0" layoutY="379.0" mnemonicParsing="false" text="发送" AnchorPane.bottomAnchor="245.0" AnchorPane.leftAnchor="653.0" />
|
||||||
<Button fx:id="add" layoutX="653.0" layoutY="90.0" mnemonicParsing="false" text="添加" />
|
<Button fx:id="connect" layoutX="847.0" layoutY="137.0" mnemonicParsing="false" text="连接" />
|
||||||
<Button fx:id="connect" layoutX="422.0" layoutY="173.0" mnemonicParsing="false" text="连接" />
|
|
||||||
<TextArea fx:id="result_show" layoutX="98.0" layoutY="410.0" prefHeight="200.0" prefWidth="1031.0" AnchorPane.bottomAnchor="39.0" AnchorPane.leftAnchor="98.0" AnchorPane.rightAnchor="71.0" />
|
<TextArea fx:id="result_show" layoutX="98.0" layoutY="410.0" prefHeight="200.0" prefWidth="1031.0" AnchorPane.bottomAnchor="39.0" AnchorPane.leftAnchor="98.0" AnchorPane.rightAnchor="71.0" />
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue