当前位置: 首页 > 知识库问答 >
问题:

Websocket(Jetty):如何在服务器端处理以块形式出现的二进制数据

邓韬
2023-03-14

我需要设置一个web套接字服务器,它可以接收客户端发送的音频数据。我用Jetty做这个。

我的处理程序代码:

{
    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
    }

    @OnWebSocketError
    public void onError(Throwable t) {
    }

    @OnWebSocketConnect
    public void onConnect(Session session) {

    }

    @OnWebSocketMessage
    public void onMessage(String message) {
    }

    @OnWebSocketMessage
    public void onMessage(bytes [] b) {
    }

    @OnWebSocketMessage
    public void inputStream(InputStream is) {
    }
}

由于音频文件相当大,客户端会将其分块发送。现在,对于每个块,都会调用onMessage(bytes[]b){}方法。

在服务器端,我需要添加这些块并处理音频。我怎么能那样做?

还有onMessage(bytes[]b){}onMessage(InputStream){}方法之间的区别是什么?

共有1个答案

杜嘉慕
2023-03-14

根据onMessagejavadoc,onMessage(字节[]b)onMessage(InputStream is)都将接收整个消息:

如果该方法正在处理二进制消息:

  • byte[]或ByteBuffer接收整个消息
  • InputStream以阻塞流的形式接收整个消息

因此,如果您使用其中一种方法,Jetty将自动重新组合块并将整个消息传递给您的方法(作为字节[]数组或输入流)。

您可以通过这种方式接收的二进制消息的最大大小由setMaxBinaryMessageSize设置

另外请注意,在Handler类中,您可能只能同时定义其中一个方法:

对于每种本机WebSocket消息格式,每个webSocketendpoint可能只有一种消息处理方法:文本、二进制和pong。

如果您想在处理数据的过程中,应该使用以下方法签名:

@OnMessage
public void processUpload(byte[] b, boolean last, Session session) {
    // process partial data here, which check on last to see if these is more on the way
}

手动缓冲您的数据(在内存或磁盘文件等)

反过来,客户端应该使用sendPartialBytes方法之一,逐块发送数据。

如果您观察到的是整个消息方法(即onMessage(byte[]b)被客户端发送的每个数据块调用,这表明客户端没有利用协议功能发送分块消息,并且确实使用了相反,将输入数据拆分,然后将其部分作为独立的WS消息发送,有效地创建了自己的应用程序级协议,用于以块形式传输数据。

在这种情况下,您必须更新客户端(如果这是一个选项),使其使用常规的WS-protocol功能,或者实现客户端使用的相同“应用程序级协议”。

下面是一个超级简单的endpoint示例,它将缓冲输入数据,直到关闭WS-socket(这意味着客户端在发送完所有数据块后将关闭连接)。

@ServerEndpoint("/data")
public static class Handler {

    private ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    @OnMessage
    public void onMessage(byte[] message) throws IOException {
        buffer.write(message);
    }

    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println(
            buffer.toByteArray().length
        );
    }

}

此实现还意味着默认ServerEndpoint Config。使用Configurator,因此每个连接正好有一个Endpoint实例(如本文所述)。

更复杂的实现可能需要重用套接字来发送多个文件,并指定一种机制来表示每次传输的开始和结束(例如,使用特殊格式的消息),但这完全取决于客户端的实现方式。

 类似资料:
  • 问题内容: 我讨厌问这样一个模糊的问题,但是我很难找到一个简单的例子。这是我到目前为止的内容: 我可以找到的嵌入式Jetty示例始终显示如下内容,以启动运行的Server实例,但我不知道如何实例化WebSocketServlet。 如何创建可以处理WebSocket连接请求的嵌入式服务器? 问题答案: 更新:2013年12月2日 有关带有WebSocket的嵌入式码头的最新示例,请参见: http

  • 问题内容: 当我使用plupload来对文件进行分块(设置选项)时,我为每个块获得了单独的PHP请求。看变量,每个块都是type 。 是否有任何简单,标准和舒适的方式在服务器端将这些片段组合到PHP中? 在保证理智的情况下(例如,缺少一件物品等)。 问题答案: 最后,我使用了与plupload-1.5.2捆绑在一起的官方示例中的代码(examples / upload.php): http://g

  • 更新如果我使用ws.close()从客户端关闭连接,那么一切都很好。

  • 本文向大家介绍ASP.NET实现图片以二进制的形式存入数据库,包括了ASP.NET实现图片以二进制的形式存入数据库的使用技巧和注意事项,需要的朋友参考一下 本文以实例形式讲述了ASP.NET实现图片以二进制的形式存入数据库的方法。过去我们都是直接在数据库中存入图片文件名的,还没有试过存储整张图片到数据库中,经过一番资料查询与测试,整理出了如下的功能代码: 1.建立保存图片的表的SQL语句: 2.下

  • 问题内容: 我已经看到了许多在Java中通过套接字发送序列化数据的示例,但是我想要的只是发送一些简单的整数和字符串。而且,问题是我正在尝试将这些信息传递给用C编写的二进制文件。 因此,最重要的是:如何在Java中通过套接字发送一些字节? 问题答案: 我真的建议不要直接使用Java Sockets库。我发现Netty(来自JBoss)非常易于实现且功能强大。Netty ChannelBuffer类带

  • 嗨,我在试图理解如何使用datatables进行服务器端处理时遇到了一些主要问题。在某些背景下,我使用一个服务调用Gamesparks为视频游戏创建后端,在这个服务中,他们有一个mongodb的实现。 我有一个endpoint可以获取所有用户,我可以在表中看到他们,但问题是我获取了所有用户,如何实现分页?。在文档中,他们声明我们必须将serverSide设置为true,但不起作用。我真的不知道如何