gpt4 book ai didi

javascript - Vertx JS Eventbus 连接正在创建然后关闭

转载 作者:太空宇宙 更新时间:2023-11-04 15:56:42 24 4
gpt4 key购买 nike

背景:在Java端使用Vertx 3.3.3 CoreWeb作为服务器,使用vertx-web-3.3 .3-client.js 作为客户端,使用 sockjsclient1.1.2.js

问题:我在本地计算机或 LAN 上成功从客户端连接到 eventbus。当我通过代理时,wss eventbus 连接被阻止(在 Firefox 中我看到“Firefox 无法建立到“wss://...”的连接;在 Chromium 中我看到“与 wss://... 的 WebSocket 连接失败:WebSocket 握手期间出错:意外的响应代码:400”,然后我看到“https ://.../eventbus/.. ./xhr_send?t=... 无法加载资源:服务器响应状态代码为 500")。但是,onopen 触发,我收到一些数据(连接降级)到接受的协议(protocol)?)。此后,onclose 立即触发,我失去了连接。我知道我已成功到达 Java vertx 服务器,因为我的静态 Web 和 API 调用正在运行。

问题:我已经广泛浏览了 Vertx 和 SockJS 文档。有没有:

  1. 有关 vertx 如何在 JS Eventbus 连接中尝试不同传输协议(protocol)的文档?
  2. 通过业务代理工作的 JS Vertx Eventbus 示例?
  3. 实现 Eventbus 连接的另一种方法,也许指定要尝试/使用的 SockJS 协议(protocol)? (我正在尝试用最简单的方法创建事件总线连接,如文档中的许多地方所示)
  4. 我需要在 SockJS/Eventbus 设置的 Java 端做些什么?

提前感谢您的任何建议/帮助!

编辑 1:为 Java 服务器和 JavaScript Web 客户端添加以下代码。网络端是非常基本的(以及失败的地方)。 Java 端使用 Spring 进行依赖项注入(inject)和应用程序配置,具有 Eventbus 连接、一次 API 调用,并提供静态 Web 内容。

从客户端到服务器的 API 调用正常,服务器正确获取 Web 内容,因此访问该工具正常。但是,代理导致 wss 失败(如预期),但降级到 xhr-streaming 失败(我认为)

Javascript:

var EB;
var URL;
var APICall = "api/eventbus/publish/";
var IncomingAddress = "heartbeat-test";
var OutgoingAddress = "client-test";

function createConnection(){
URL = $("#serveraddressinput").val(); //Getting url from html text box
console.log("Creating Eventbus connection at " + URL + "eventbus"); //Eventbus address is '<link>/eventbus'
EB = new EventBus(URL + "eventbus");

testAPICall();

EB.onopen = function(){
console.log("Eventbus connection successfully made at " + URL + "eventbus");
console.log("Registering Eventbus handler for messages at " + IncomingAddress);

EB.registerHandler(IncomingAddress, function(error, message){
console.log("Received Eventbus message " + JSON.stringify(message));
};

EB.onclose = function(){
console.log("Eventbus connection at " + URL + " has been lost");
URL = "";
};
}

function testAPICall(){
var link = URL + APICall + "heartbeat-test";
console.log("Testing API call to " + link);
$.ajax({
url: link,
type: 'POST',
data: JSON.stringify({"testFromClient": "Test message sent from Client via API Call"}),
dataType: 'json',
success: function (data, textStatus) {
console.log("API Call Success: " + JSON.stringify(data));
},
error: function (request, error) {
console.log("API Call ERROR: " + JSON.stringify(request) + " " + error);
}
});
}

function sendTestMessage(){
console.log("Sending test message to address " + OutgoingAddress);
EB.send(OutgoingAddress, "Testing 1, 2, 3...");
}

Java:

...

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.JksOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.handler.sockjs.BridgeEvent;
import io.vertx.ext.web.handler.sockjs.BridgeEventType;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.PermittedOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
import org.apache.logging.log4j.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class MyTestVerticle extends AbstractVerticle {

private final static Logger log = LoggerFactory.getLogger(MyTestVerticle.class);

final Level ACCESS = Level.forName("ACCESS", 450);

private boolean started;

private int port;

@Value("${webserver.testpath.enabled}")
private boolean testPathEnabled;

@Value("${webserver.urlpath.test}")
private String testUrlPath;

@Value("${webserver.filepath.test}")
private String testFilePath;

@Value("${webserver.caching.enabled}")
private boolean cachingEnabled;

@Value("${webserver.ssl.enabled}")
private boolean sslEnabled;

private BridgeOptions bridgeOptions;

private SockJSHandler sockJsHandler;

private Router router;

private JksOptions sslKeyStoreOptions;

private JksOptions sslTrustStoreOptions;

public MyTestVerticle() {
this.started = false;
}

@Override
public void start(Future<Void> fut) throws Exception {
log.info("start() -- starting Vertx Verticle with eventbus, API handler, and static file handler");

// grab the router
router = getRouter();

// enable CORS for the router
CorsHandler corsHandler = CorsHandler.create("*"); //Wildcard(*) not allowed if allowCredentials is true
corsHandler.allowedMethod(HttpMethod.OPTIONS);
corsHandler.allowedMethod(HttpMethod.GET);
corsHandler.allowedMethod(HttpMethod.POST);
corsHandler.allowedMethod(HttpMethod.PUT);
corsHandler.allowedMethod(HttpMethod.DELETE);
corsHandler.allowCredentials(false);
corsHandler.allowedHeader("Access-Control-Request-Method");
corsHandler.allowedHeader("Access-Control-Allow-Method");
corsHandler.allowedHeader("Access-Control-Allow-Credentials");
corsHandler.allowedHeader("Access-Control-Allow-Origin");
corsHandler.allowedHeader("Access-Control-Allow-Headers");
corsHandler.allowedHeader("Content-Type");

// enable handling of body
router.route().handler(BodyHandler.create());
router.route().handler(corsHandler);
router.route().handler(this::handleAccessLogging);

// publish a payload to provided eventbus destination
router.post("/api/eventbus/publish/:destination").handler(this::publish);

// open up all for outbound and inbound traffic
bridgeOptions = new BridgeOptions();
bridgeOptions.addOutboundPermitted(new PermittedOptions().setAddressRegex(".*"));
bridgeOptions.addInboundPermitted(new PermittedOptions().setAddressRegex(".*"));
// sockJsHandler = SockJSHandler.create(vertx).bridge(bridgeOptions);
sockJsHandler = SockJSHandler.create(vertx);
sockJsHandler.bridge(bridgeOptions, be -> {
try {
if (be.type() == BridgeEventType.SOCKET_CREATED) {
handleSocketOpenEvent(be);
}
else if(be.type() ==BridgeEventType.REGISTER) {
handleRegisterEvent(be);
}
else if(be.type() ==BridgeEventType.UNREGISTER) {
handleUnregisterEvent(be);
}
else if(be.type() ==BridgeEventType.SOCKET_CLOSED) {
handleSocketCloseEvent(be);
}
} catch (Exception e) {

} finally {
be.complete(true);
}
});
router.route("/eventbus/*").handler(sockJsHandler);

if(testPathEnabled){
router.route("/" + testUrlPath + "/*").handler(StaticHandler.create(testFilePath).setCachingEnabled(cachingEnabled));
}

// create periodic task, pushing all current EventBusRegistrations
vertx.setPeriodic(1000, handler -> {
JsonObject obj =new JsonObject();
obj.put("testMessage", "Periodic test message from server...");
vertx.eventBus().publish("heartbeat-test", Json.encodePrettily(obj));
});

EventBus eb = vertx.eventBus();
eb.consumer("client-test", message -> {
log.info("Received message from client: " + Json.encodePrettily(message.body()) + " at " + System.currentTimeMillis());
});

HttpServerOptions httpOptions = new HttpServerOptions();
if(sslEnabled){
httpOptions.setSsl(true);
httpOptions.setKeyStoreOptions(sslKeyStoreOptions);
}

log.info("starting web server on port: " + port);
vertx
.createHttpServer(httpOptions)
.requestHandler(router::accept).listen(
port,
result -> {
if (result.succeeded()) {
setStarted(true);
log.info("Server started and ready to accept requests");
fut.complete();
} else {
setStarted(false);
fut.fail(result.cause());
}
}
);
}

private void handleSocketOpenEvent(BridgeEvent be){
String host =be.socket().remoteAddress().toString();
String localAddress = be.socket().localAddress().toString();
log.info("Socket connection opened! Host: " + host + " Local address: " + localAddress);
}

private void handleRegisterEvent(BridgeEvent be){
String host =be.socket().remoteAddress().toString();
String localAddress = be.socket().localAddress().toString();
String address = be.getRawMessage().getString("address").trim();
log.info("Eventbus register event! Address: " + address + " Host: " + host + " Local address: " + localAddress);
}

private void handleUnregisterEvent(BridgeEvent be){
String host =be.socket().remoteAddress().toString();
String localAddress = be.socket().localAddress().toString();
String address = be.getRawMessage().getString("address").trim();
log.info("Eventbus unregister event! Address: " + address + " Host: " + host + " Local address: " + localAddress);
}

private void handleSocketCloseEvent(BridgeEvent be){
String host =be.socket().remoteAddress().toString();
String localAddress = be.socket().localAddress().toString();
log.info("Socket connection closed! Host: " + host + " Local address: " + localAddress);
}

//Method handles logging at custom level for access logging to files
private void handleAccessLogging(RoutingContext routingContext){
Marker accessMarker = MarkerFactory.getMarker("ACCESS");

if(routingContext.normalisedPath().contains("/api")){
log.info(accessMarker, "Api access log: request= " + routingContext.normalisedPath() + " source=" + routingContext.request().remoteAddress());
}
else{
log.info(accessMarker, "Web access log: path= " + routingContext.normalisedPath() + " source= " + routingContext.request().remoteAddress());
}

routingContext.next();
}

/**
* Accept a payload (anything) and publish to the provided destination
*
* @param routingContext
*/
private void publish(RoutingContext routingContext) {
String destination = routingContext.request().getParam("destination");
String payload = routingContext.getBodyAsString();
if ((destination == null) || (payload == null)) {
Exception e = new Exception("Missing arguments");
routingContext.response().setStatusCode(406);
routingContext.fail(e);
} else {
log.info("API Call -> Publishing to destination: " + destination + " payload: " + payload);
vertx.eventBus().publish(destination, payload);
routingContext
.response()
.setStatusCode(200)
.putHeader("content-type", "application/json; charset=utf-8")
.end(payload);
}
}

public boolean isStarted() {
return started;
}

public void setStarted(boolean started) {
this.started = started;
}

public int getPort() {
return port;
}

public void setPort(int port) {
this.port = port;
}

public Router getRouter(){
if(router == null){
router = Router.router(vertx);
}
return router;
}

public void setRouter(Router router){
this.router = router;
}

public void setSslOptions(JksOptions keyStoreOptions, JksOptions trustStoreOptions) {
this.sslKeyStoreOptions = keyStoreOptions;
this.sslTrustStoreOptions = trustStoreOptions;
}
}

最佳答案

可以通过执行以下操作解决此错误:

  1. 在 Java verticle 中,将 Eventbus 处理程序移动到顶部,位于任何其他处理程序之前。我相信 BodyHandler 或 CorsHandler 搞砸了并导致 500 错误。

    ...
    router.route("/eventbus/*").handler(sockJsHandler);
    ...
    // enable handling of body
    router.route().handler(BodyHandler.create());
    router.route().handler(corsHandler);
    router.route().handler(this::handleAccessLogging);

    // publish a payload to provided eventbus destination
    router.post("/api/eventbus/publish/:destination").handler(this::publish);

关于javascript - Vertx JS Eventbus 连接正在创建然后关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42635287/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com