我需要有关接收和发送 Web 套接字消息的建议

问题描述 投票:0回答:1

我按照教程编写了一个可以通过 Twilio SDK 调用的应用程序,该应用程序打开 WebSocket 连接。我正在使用 Spring Boot,现在我希望能够在电话中通话并使用 Azure 认知服务将其转录为文本,并对文本执行一些操作。将文本转换回语音并将其发送到手机。我的问题是,当我说某件事时,我会将其发送到 Azure 并取回,但在手机中它会重复很多次。而不是一次。下面是通过套接字接收和发送消息的方法:

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException, InterruptedException {
    JsonNode request = jsonMapper.readTree(message.getPayload());

    if (request.path("media").path("track").asText().equals("inbound")) {
        String base64EncodedAudio = request.path("media").path("payload").asText();

        if (payloads.size() > 200) {
            String response = contructResponse(session, request);
            session.sendMessage(new TextMessage(response));
            payloads.clear();
        } else {
            payloads.add(base64EncodedAudio);
        }
    }
}

private String contructResponse(WebSocketSession session, JsonNode request) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    String streamSid = request.path("streamSid").asText();

    for (int i = 0; i < payloads.size(); i++) {
        byte[] decoded = base64Decoder.decode(payloads.get(i));
        sessions.get(session).pushData(decoded);
        decoded = sessions.get(session).getBytes();

        if (decoded != null)
            outputStream.write(decoded);
    }

    byte[] encodedBytes = Base64.getEncoder().encode(outputStream.toByteArray());

    return objectMapper.writeValueAsString(new OutBoundMessage("media", new Media(new String(encodedBytes)), streamSid));
}

我的希望是,一旦收到 200 条消息,我将连接这些消息中的音频,进行天蓝色处理,然后发回一条消息,因为列表有效负载在此之后被清除且不超过 200 条。但似乎并非如此。它是否在不同的线程上工作,而所有天蓝色的东西都在另一个线程上进行,并在清除有效负载之前不断添加消息?有人有意见吗?

java spring-boot azure websocket twilio
1个回答
0
投票

我不知道到底发生了什么,但我的猜测是,对

constructResponse
session.sendMessage
的调用可能比另一条 websocket 消息到达所需的时间更长,因此在您能够之前,会重复该过程清除
payloads

能否克隆

payloads
,清除原始
payloads
列表,然后将克隆传递给
constructResponse
方法?

类似:

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException, InterruptedException {
    JsonNode request = jsonMapper.readTree(message.getPayload());

    if (request.path("media").path("track").asText().equals("inbound")) {
        String base64EncodedAudio = request.path("media").path("payload").asText();
        payloads.add(base64EncodedAudio);

        if (payloads.size() > 200) {
            // Clone the current members of payloads, I think this will work, excuse the type if it's wrong
            ArrayList<String> clonedPayloads = payloads.clone();
            payloads.clear();

            String response = contructResponse(clonedPayloads, session, request);
            session.sendMessage(new TextMessage(response));
        }
    }
}

然后更改

constructResponse
以接收克隆的有效负载列表作为参数:

private String contructResponse(ArrayList<String> payloads, WebSocketSession session, JsonNode request) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    String streamSid = request.path("streamSid").asText();

    for (int i = 0; i < payloads.size(); i++) {
        byte[] decoded = base64Decoder.decode(payloads.get(i));
        sessions.get(session).pushData(decoded);
        decoded = sessions.get(session).getBytes();

        if (decoded != null)
            outputStream.write(decoded);
    }

    byte[] encodedBytes = Base64.getEncoder().encode(outputStream.toByteArray());

    return objectMapper.writeValueAsString(new OutBoundMessage("media", new Media(new String(encodedBytes)), streamSid));
}
© www.soinside.com 2019 - 2024. All rights reserved.