关于 Vert.x-tcp-eventbus-bridge 的详细用法,Vert.x 的官方文档(官方文档1、官方文档2)都写得很简单,简单得还是让人搞不懂如何使用。
从网上找到了一篇介绍如何使用的文章:Vert.x TCP EventBus Bridge补遗。该项目中的例子源码在 github 上。看了源码之后,发现是一个 groovy项目。于是就将例子用 Java 代码重新写了下。总共有如下几个文件:
1. pom 文件
4.0.0
io.example
vertx-example
1.0-SNAPSHOT
UTF-8
3.4.2
io.vertx.core.Launcher
io.example.MainVerticle
20.0
io.vertx
vertx-core
${vertx.version}
io.vertx
vertx-web
${vertx.version}
io.vertx
vertx-tcp-eventbus-bridge
${vertx.version}
com.google.guava
guava
${guava.version}
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
org.apache.maven.plugins
maven-shade-plugin
3.1.1
package
shade
${main.class}
${main.verticle}
${project.build.directory}/${project.artifactId}-${project.version}-prod.jar
2. MainVerticle
package io.example;
import io.example.tcp.TcpClientVerticle;
import io.example.tcp.TcpServerVerticle;
import io.vertx.core.AbstractVerticle;
/**
*
*/
public class MainVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
// TCP EventBus Bridge
vertx.deployVerticle(TcpServerVerticle.class.getName());
vertx.deployVerticle(TcpClientVerticle.class.getName());
}
}
3. TcpServerVerticle
package io.example.tcp;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.ext.bridge.BridgeOptions;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.eventbus.bridge.tcp.TcpEventBusBridge;
public class TcpServerVerticle extends AbstractVerticle {
TcpEventBusBridge bridge;
int port = 8086;
@Override
public void start(Future startFuture) throws Exception {
vertx.eventBus().consumer("echo", message -> {
System.out.println("Server received->" + message.body());
message.reply(message.body());
});
BridgeOptions options = new BridgeOptions()
.addInboundPermitted(new PermittedOptions().setAddress("echo"))
.addOutboundPermitted(new PermittedOptions().setAddress("echo"));
bridge = TcpEventBusBridge.create(vertx, options);
bridge.listen(port, result -> {
if (result.succeeded()) {
System.out.println("Bridge started at port " + port);
} else {
System.out.println("Bridge failed");
result.cause().printStackTrace();
}
});
startFuture.complete();
}
@Override
public void stop() throws Exception {
bridge.close();
}
}
4. TcpClientVerticle
package io.example.tcp;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetSocket;
import io.vertx.ext.eventbus.bridge.tcp.impl.protocol.FrameHelper;
import io.vertx.ext.eventbus.bridge.tcp.impl.protocol.FrameParser;
public class TcpClientVerticle extends AbstractVerticle {
NetSocket netSocket;
@Override
public void start(Future startFuture) throws Exception {
NetClient client = vertx.createNetClient();
client.connect(8086, "127.0.0.1", result -> {
if (result.succeeded()) {
System.out.println("NetClient连接成功");
netSocket = result.result();
vertx.setPeriodic(1000L, l ->
FrameHelper.sendFrame("send",
"echo",
"echo",
new JsonObject().put("hello", "world"),
netSocket)
);
netSocket.handler(new FrameParser(bufferResult -> {
if (bufferResult.succeeded()) {
JsonObject resultObj = bufferResult.result();
System.out.println("解析Buffer成功->" + resultObj.toString());
} else {
System.out.println("解析Buffer失败");
}
}));
} else {
System.out.println("NetClient连接失败");
result.cause().printStackTrace();
}
});
startFuture.complete();
}
@Override
public void stop() throws Exception {
netSocket.close();
}
}
在改写完这个例子后突然想到一个问题:既然是直接处理 TCP 且文档中给出了协议的格式,那直接使用 Java 的 TCP 即可与Vert.x-tcp-eventbus-bridge 进行通信了。所以又写了个 TCP 直接与 Vert.x-tcp-eventbus-bridge 通信的示例代码。如果项目中不想依赖 Vert.x 相关的 jar 包,下面示例代码中的 JsonObject 可替换为其他 json 库的 JSONObject。
package io.example.tcp;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints;
import io.vertx.core.json.JsonObject;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TcpClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8086);
OutputStream out = socket.getOutputStream();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
String requestJsonStr = new JsonObject()
.put("type", "send")
.put("address", "echo")
.put("replyAddress", "echo")
.put("body", new JsonObject().put("time", "Now is " + time))
.toString();
byte[] requestJsonBytes = requestJsonStr.getBytes(StandardCharsets.UTF_8);
byte[] lengthBytes = Ints.toByteArray(requestJsonBytes.length);
// Frame字节数组
byte[] frameBytes = Bytes.concat(lengthBytes, requestJsonBytes);
out.write(frameBytes);
out.flush();
System.out.println("发送信息完成->" + requestJsonStr);
byte[] bytes = new byte[1024];
InputStream in = socket.getInputStream();
int len = in.read(bytes);
String responseStr = new String(bytes, 4, len - 4);
System.out.println("Response->" + responseStr);
out.close();
in.close();
socket.close();
}
}