2016-11-09 90 views
1

我試圖建立一個基本的HTTP和WebSocket的Vert.x服務器,但WebSocket的路線總是返回200而不是101Vert.x的WebSocket返回200,而不是101

public class PhilTheServer extends AbstractVerticle { 

    private final static int PORT = 8080; 

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

     // We need cookies, sessions and request bodies 
     router.route().handler(CookieHandler.create()); 
     router.route().handler(BodyHandler.create()); 

     router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))); 

     // Simple auth service which uses a properties file for user/role info 
     AuthProvider authProvider = ShiroAuth.create(vertx, new ShiroAuthOptions() 
       .setType(ShiroAuthRealmType.PROPERTIES) 
       .setConfig(new JsonObject() 
        .put("properties_path", "src/main/resources/vertx-users.properties"))); 

     // We need a user session handler too to make sure the user is stored in the session between requests 
     router.route().handler(UserSessionHandler.create(authProvider)); 

     // Serve the static private pages from directory "webroot" 
     router.route("/static/*").handler(StaticHandler.create("webroot/static").setCachingEnabled(false)); 

     // Public Index Page 
     router.get("/").handler(ctx -> { 
      ctx.response().sendFile("webroot/index.html"); 
     }); 

     router.mountSubRouter("/api", APIRoutes.get(vertx, authProvider)); 

     // Default non-handled requests: 
     router.route().handler(ctx -> { 
      ctx.fail(404); 
     }); 

     // WEBSOCKET: 

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

     // Create the event bus bridge and add it to the router. 
     SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts, event -> { 
      if (event.type() == BridgeEventType.SOCKET_CREATED) { 
       System.out.println("A socket was created"); 
      } else { 
       System.out.println(event.type()); 
      } 

      event.complete(true); 
     }); 

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

     // Create the HTTP server and pass the "accept" method to the request handler. 
     vertx 
      .createHttpServer() 
      .requestHandler(router::accept) 
      .listen(
        // Retrieve the port from the configuration, 
        // default to 8080. 
        config().getInteger("http.port", 8080), 
        result -> { 
         if (result.succeeded()) { 
          fut.complete(); 
         } else { 
          fut.fail(result.cause()); 
         } 
        } 
      ); 
    } 
} 

而不是增加一個SockJSHanlder,我試圖在HttpServer上使用websocketHandler,這工作正常,但我想反過來做。

我的測試代碼:在您的列表

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

更高:

HttpClient httpClient = client.websocket(PORT, "localhost", "/eventbus", headers, ws -> { 
    ws.handler(buffer -> { 
     JsonObject message = new JsonObject(buffer.toString()); 

     assertTrue(message.containsKey("type")); 

     ws.close(); 

     async.complete(); 
    }); 

    ws.write(Buffer.buffer("{ \"type\": \"test\"}")); 
}); 

回答

2

你應該將處理程序。問題是你有全局的處理程序將被首先執行,並且不允許這個處理程序處理協議升級到sockjs。這些處理程序是:

router.route().handler(CookieHandler.create()); 
router.route().handler(BodyHandler.create()); 
router.route().handler(SessionHandler....); 
router.route().handler(ctx -> { 
    ctx.fail(404); 
}); 

由於router.route()將呼籲他們將與您的協議干擾升級的任何路徑。如果你先移動sockjs處理程序,那麼它應該先執行,你的代碼應該可以工作。

相關問題