使用VertX将消息从eventbus桥接到订阅的websocket客户端

时间:2017-01-07 00:03:37

标签: java websocket vert.x sockjs

我尝试使用websocket创建一个发布 - 宿责模型,可以通过SockJS和Websocket来访问(一方面是Javascript客户端,另一方面是Java客户端。

目前我可以使用SockJS和Javascript客户端订阅。但是,当我尝试使用websocket在我的Java客户端中接收消息时,我能够连接到websocket服务器,但是没有从服务器接收任何消息。

我当前的客户代码:

public class WebsocketReceiverIntegrationTest {
    public static void main(String[] args) {
        System.out.println("Started demo WS client");
        HttpClient client = Vertx.vertx().createHttpClient();

        System.out.println("Will now connect to WS server");
        client.websocket(8091, "localhost", "/", webSocket -> {
           webSocket.handler( data -> {
                System.out.print("Received data " + data.toString("ISO-8859-1"));
           });
        });

        System.out.println("Ready to receive data");

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext() && ! scanner.next().equals("q")) {
        }

        System.out.println("Stopped");
        client.close();
    }
}

我当前服务器代码中的相关位:

@Override
public void start(Future<Void> fut) {
    Router router = Router.router(vertx);

    router.route("/eventbus/*").handler(sockJSEventBusHandler());

    router.route().failureHandler(errorHandler());

    vertx.createHttpServer().websocketHandler(serverWebSocket -> {
        System.out.print("Websocket client connected!");
        vertx.eventBus().consumer(serverWebSocket.textHandlerID());
    }).listen(8091);

    vertx.setPeriodic(1000, id -> {
        vertx.eventBus().send("gameupdates", Json.encodePrettily(tickGameState()));
    });
}

private SockJSHandler sockJSEventBusHandler() {
    BridgeOptions options = new BridgeOptions().addOutboundPermitted(new PermittedOptions().setAddress(GAMEUPDATE_CHANNEL_NAME));
    return SockJSHandler.create(vertx).bridge(options, event -> {
        if (event.type() == BridgeEventType.SOCKET_CREATED) {
            logger.info("A socket was created");
        }
        event.complete(true);
    });
}

2 个答案:

答案 0 :(得分:1)

您可以通过两种方式处理请求:

  
      
  1. Router路由incoming request并回复回复。
  2.   
     public void start(Future<Void> fut) {
         Router router = Router.router(vertx);


           BridgeOptions opts = new BridgeOptions()
           .addInboundPermitted(new PermittedOptions().setAddressRegex(".*"))
           .addOutboundPermitted(new  PermittedOptions().setAddressRegex(".*"));


          SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
          router.route("/eventbus/*").handler(ebHandler);
          router.route("/eventbus/").handler(this::getApi);
          ...
          router.route().handler(StaticHandler.create());
      }


     private void getApi(RoutingContext routingContext) {
           routingContext.response().setStatusCode(201).putHeader("content-type", "application/json; charset=utf-8")
              .end("ok");
      }

您可以使用Router实施GET / POST / PUT和DELETE,请参阅此文档以获取更多信息:REST API with Vert.x Web

  
      
  1. 在部署Tunnel
  2. 时创建Vertical的另一种方法   
  EventBus eb = vertx.eventBus();

public void start(Future<Void> fut) {
     Router router = Router.router(vertx);


       BridgeOptions opts = new BridgeOptions()
       .addInboundPermitted(new PermittedOptions().setAddressRegex(".*"))
       .addOutboundPermitted(new  PermittedOptions().setAddressRegex(".*"));


      SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
      router.route("/eventbus/*").handler(ebHandler);
      router.route("/eventbus/").handler(this::getApi);
      ...
      router.route().handler(StaticHandler.create());

     createListenerTunnel(addressToServer, addressToClient);

  }

private void createListenerTunnel(String addressToServer, String addressToClient) {
eb.consumer(string).handler(message -> {
        String timestamp = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
                .format(Date.from(Instant.now()));

        eb.publish("local-message-receiver", timestamp  + ":" + message.body());


    });
}

其中ebEventBus对象,为部署的垂直引用相同的port

您可以参考此example

答案 1 :(得分:1)

请注意,SockJS协议支持来自regular websocket clients的连接。例如,如果您在/api/realtime注册了SockJSHandler,那么您应该可以使用websocket客户端连接到/api/realtime/websocket