如何在Javascript中从Vert.x服务器接收websocket消息?

4
我正在尝试使用Java中的Vert.x创建包含WebSockets的HTTP服务器,同时使用JavaScript编写客户端而不使用vertx.js。我避免在客户端中使用Vert.x,因为它应该保持基于浏览器(像browserfy这样的工具无法成功将Vert.x的CommonJS标准转换为可供浏览器使用的代码)。
在为服务器和客户端编写测试代码后,我尝试了向服务器发送消息、获取其数据并用任意响应进行回复的简单示例。服务器接收到了消息并能够读取内容。然而,客户端只收到了一条消息,没有得到预期的内容。客户端无法将通过websocket接收到的事件数据转换为字符串(根本没有字符串数据?)。使用indexof.js来确定事件数据的字节大小,在多次更改服务器发送的内容后,结果始终保持在34字节的恒定大小。我尝试在服务器端使用writeMessage和write方法向客户端WebSocket发送数据,结果仍然相同。
为什么我的客户端只会在WebSocket上接收到恒定大小的数据,如何使其正常工作?
感谢您的建议!

编辑: 我使用writeFrame方法替换了writewriteMessage方法。使用writeFrame可以发送二进制数据和纯文本。从基于Java的服务器向基于Javascript的客户端以这种方式发送文本可以正常工作。我仍然不知道如何处理客户端的二进制消息,但它仍然是有益的。虽然文本消息可以正常工作,但它们被认为仍然具有相同的大小(34字节)。我以为收到的数据对象会因大小而异,但似乎它只是一个指向实际数据的对象。

------------------------------------------------

客户端代码是在使用Java Servlets和Websockets进行(成功的)测试期间编写的:
var wsUri = "ws://" + document.location.host + document.location.pathname + "chat";

var websocket = new WebSocket(wsUri);
websocket.onerror = function(evt) { onError(evt) };
websocket.onopen = function (evt) { onOpen(evt) };

function onError (evt)
{
    debugMessage('<span style="color: red;">ERROR:</span> ' + evt.data);
}

function onOpen (evt)
{
//    debugMessage("Connected to " + wsUri);
    debugMessage("GOTCHA!");
}

websocket.onmessage = function (evt) { onMessage(evt) };

function onMessage (evt)
{
    debugMessage(evt.toString());
    debugMessage(evt.data.toString());
    debugMessage(sizeof(evt.data));
}

function sendMessage (msg)
{
    websocket.send(msg);
}

function sendDebugMessage ()
{
    websocket.send("Hiho Wursty!");
    debugMessage("Did send Wursty-message.");
}

服务器端的实现参照了官方Vert.x文档以及另一个在线教程

server = vertx.createHttpServer();

server.requestHandler(request -> {
    handleRequest(request);
});

server.websocketHandler(ws -> {
    print("Websocket-handshake...");
    print("path = " + ws.path());
    print("uri = " + ws.uri());
    print("localAdress = " + ws.localAddress().toString());
    print("remoteAddress = " + ws.remoteAddress());
    print(ws.toString());

    if (!ws.path().equals("/chat")) {
        ws.reject();
    } else {
        SharedData sd = vertx.sharedData();
        LocalMap<String, String> wsChatSessions =
                sd.getLocalMap("ws.chat.sessions");

        wsChatSessions.put(ws.textHandlerID(), ws.toString());

        ws.closeHandler(ch -> {
            print("Closing ws-connection to client " + ws.textHandlerID());
            wsChatSessions.remove(ws.textHandlerID());
        });

        ws.handler(new Handler<Buffer>(){
            @Override
            public void handle(final Buffer data) {
                String msg = data.getString(0, data.length());
                print("Message from ws-client " + ws.textHandlerID() 
                        + ": " + msg);
                Buffer resp = Buffer.buffer();
                resp.appendString("O Ding Dong asd asda sdasd a"
                        + "asdasd asd asdasda sdas dasd adads asd as"
                        + "as dasd asd asd asd asdasd asdasdasd "
                        + "asdasd asd asd asd asd asda sdasd asd !");
                ws.writeMessage(resp);
                ws.write(resp);
            }
        });
    }
});

server.listen(port, res -> {
    if (res.succeeded()){
        print("Listening...");
    } else{
        print("Failed to bind! -> Server is not listening"
            + " to incoming client connections.");
    }
});
1个回答

5

我收到的0字节大小的消息原因相对简单:在Javascript-websocket中,可以定义websocket从服务器接收到的(二进制)数据类型,即binaryType。默认情况下,它设置为"blob"。在我的情况下,我假设要接收arraybuffers。相应地设置选项使websocket按预期传递数据:

websocket.binaryType = "arraybuffer";

为了使用它,仍需要从arraybuffer创建一个数组。在我的案例中,我创建了一个无符号8位整数的数组:
var dataBytes = new Uint8Array(evt.data);

现在数据已经准备好,可以被后续代码处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接