2017-12-06 2 views
0

나는 간단한 Vertx 기반 websocket 채팅 응용 프로그램을 보유하고 있습니다. MsgServerVerticle과 MsgClientVerticle (아래 소스 코드)의 두 부분으로 구성됩니다. 그래서 하나의 서버와 하나의 클라이언트를 인스턴스화하는 경우 정상적으로 작동하는 것처럼 보입니다. 두 번째 클라이언트가 연결되면 서버는 다른 클라이언트에이를 알리려고하기 시작합니다. 그리고 이상한 일들. Log는 백업 된 netty가 반복적으로 websocket 프레임을 인코딩 - 디코딩한다고 말합니다. 어떤 유형의 프레임, 바이너리 또는 텍스트를 사용하든, 이슈는 동일합니다. log screenshot hereVertx Websockets는 두 번째 클라이언트를 연결 한 후 루프 내에서 인코딩 - 디코딩을 시작합니다.

무엇이 잘못 되었습니까?

MsgClientVerticle 소스 코드 :

private Logger L; 

private String eBusTag; 
private String backwardTag; 
private String targetHost; 
private int port; 
private String id; 
private String path; 

private EventBus eBus; 

private HttpClient client; 

public MsgClientVerticle(String eBusTag, String targetHost, int port, String path, String id, String backwardTag) { 
    this.eBusTag = eBusTag; 
    this.targetHost = targetHost; 
    this.path = path; 
    this.port = port; 
    this.id = id; 
    this.backwardTag = backwardTag; 

    L = LoggerFactory.getLogger(eBusTag); 
} 

@Override 
public void start(Future<Void> startFuture) throws Exception { 
    L.info("Initializing client connection to " + targetHost + ":" + port + path); 
    eBus = vertx.eventBus(); 

    try { 


     client = vertx.createHttpClient(); 

     client.websocket(port, targetHost, path, webSock -> { 
      L.info("Connected to " + targetHost + ":" + port + "/" + path); 
      eBus.publish(backwardTag, Utils.msg("Connected")); 
      webSock.binaryMessageHandler(buf -> { 
       eBus.publish(backwardTag, Utils.bufToJson(buf)); 
      }); 
      eBus.consumer(eBusTag).handler(msg -> { 
       JsonObject message = (JsonObject) msg.body(); 
       webSock.writeBinaryMessage(Utils.jsonToBuf(message)); 
      }); 
     }); 
    } catch (NullPointerException e) { 
     L.error("Null Pointer: " + e.getLocalizedMessage()); 
     e.printStackTrace(); 
    } 


    startFuture.complete(); 
} 

@Override 
public void stop(Future<Void> stopFuture) throws Exception { 
    L.info("Connection to " + targetHost + ":" + port + "/" + path + " closed"); 
    client.close(); 
    stopFuture.complete(); 
} 

그리고 MsgServerVerticle 소스 :

private Logger L; 

private String path; 
private int port; 
private String eBusTag; 
private String backwardTag; 

private HttpServer server; 

private EventBus eBus; 

private Set<ServerWebSocket> conns; 

public MsgServerVerticle(int port, String eBusTag, String backwardTag) { 
    this.port = port; 
    this.eBusTag = eBusTag; 
    this.backwardTag = backwardTag; 

    conns = new ConcurrentSet<>(); 
    path = eBusTag; 

    L = LoggerFactory.getLogger(eBusTag); 

} 

@Override 
public void start(Future<Void> startFuture) throws Exception { 
    eBus = vertx.eventBus(); 
    L.info("Initializing server instance at port " + port); 

    server = vertx.createHttpServer(); 

    server.websocketHandler(webSock -> { 

     if (!webSock.path().equals(path)) { 

      webSock.reject(); 

     } else { 

      conns.add(webSock); 

      conns.forEach(sock -> { 
       if (sock != webSock) { 
        sock.writeBinaryMessage(Utils.jsonToBuf(Utils.msg("SERVER: new client " + webSock.remoteAddress().toString()))); 
       } 
      }); 

      eBus.publish(backwardTag, Utils.msg("SERVER: new client " + webSock.remoteAddress().toString())); 

      webSock.binaryMessageHandler(buf -> { 
       JsonObject msg = Utils.bufToJson(buf); 
       conns.forEach(sock -> { 
        if (sock != webSock) { 
         sock.writeBinaryMessage(buf); 
        } 
       }); 
       eBus.publish(backwardTag, msg); 
      }); 

     } 

    }); 

    server.listen(port); 

    startFuture.complete(); 
} 

@Override 
public void stop(Future<Void> stopFuture) throws Exception { 
    conns.forEach(sock -> { 
     sock.writeFinalTextFrame("Server is shutting down..."); 
    }); 
    server.close(); 
    stopFuture.complete(); 
} 

답변

0

나는 원래 문제를 재현 할 수 없습니다. 하지만 먼저 테스트를하기 위해 몇 가지 변경을해야했습니다.

this.path = "/" + eBusTag;

그렇지 않으면이 체크는 항상 실패합니다 :

if (!webSock.path().equals(this.path)) {

websock.path() 때문에 항상 /anything 따라서, / 시작합니다 =/

하나의 변화는 서버의 초기화에 = anything

둘째, 내가 클라이언트를 초기화하는 방법을 살펴, 당신은 동일한 작업을 수행하는지 확인하십시오, 지금까지 내가 이해할 수 있기 때문에, 당신의 Utils 클래스를 사용하면 구현 뭔가

final Vertx vertx = Vertx.vertx(); 

    vertx.deployVerticle(new MsgServerVerticle(8080, 
      "ebus", 
      "back"), new DeploymentOptions().setWorker(true), (r) -> { 
     vertx.deployVerticle(new MsgClientVerticle("ebus", 
       "127.0.0.1", 
       8080, 
       "/ebus", 
       "a", 
       "back"), new DeploymentOptions().setWorker(true), (r2) -> { 
      vertx.deployVerticle(new MsgClientVerticle("ebus", 
        "127.0.0.1", 
        8080, 
        "/ebus", 
        "b", 
        "back"), new DeploymentOptions().setWorker(true), (r3) -> { 
       System.out.println("Done"); 
      }); 
     }); 
    }); 

그리고 세 번째입니다. 내 구현은 다음과 같습니다.

public class Utils { 
    public static Buffer jsonToBuf(final JsonObject message) { 
     return message.toBuffer(); 
    } 

    public static JsonObject bufToJson(final Buffer buf) { 
     return buf.toJsonObject(); 
    } 

    public static JsonObject msg(final String msg) { 
     return new JsonObject("{\"value\":\"" + msg + "\"}"); 
    } 
} 

희망 사항은 문제를 정확히 파악하는 데 도움이됩니다.

관련 문제