c++websocketaudio-streamingpocopcm

Poco C++ WebSocket Binary data send error


I am using Poco::Net::WebSocekt for stream audio-raw (PCM) over third-party STT but the problem is that unable to send that only receiving the first message from third-party socket '{type:'connected',id:'111034'}' but then an unexpected message received is happening and no any data is receiving at third party end.

Any suggest or direction will sort my problem.

I contacted Third Party they are saying that you are not sending proper 'content-type'.

#pragma once

#include "Poco/Net/HTTPRequest.h"
#include <Poco/Net/HTTPSClientSession.h>
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPMessage.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Buffer.h"
#include "Poco/URI.h"
#include "logger.h"

extern "C"
{
#include "binn/binn.h"
#pragma comment(lib,"binn.lib")
}

using Poco::Net::WebSocketException;
using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage;
using Poco::Net::WebSocket;
using Poco::Buffer;


class PocoHelper
{
    WebSocket* m_psock;
    HTTPSClientSession* cs;
    HTTPRequest* request;
    HTTPResponse response;
    Log logHelper;
    int msgSize = 8000;
    Buffer<char>* container;
    Poco::URI* uri;

public:
    PocoHelper(std::string wsEndPoint)
    {
        uri = new Poco::URI(wsEndPoint);

        cs = new HTTPSClientSession(uri->getHost(), 443);

        request = new HTTPRequest(HTTPRequest::HTTP_GET, uri->getPathEtc(), HTTPMessage::HTTP_1_1);
        request->set("origin", "http://localhost");
        request->set("content-type", "audio/x-wav;layout=interleaved;rate=32000;format=S16LE;channels=1");
        request->setKeepAlive(true);

        m_psock = new WebSocket(*cs, *request, response);

        m_psock->setBlocking(false);
        m_psock->setReceiveTimeout(Poco::Timespan(3, 0));
        m_psock->setSendTimeout(Poco::Timespan(3, 0));
        container = new Buffer<char>(msgSize);

        if (m_psock->poll(Poco::Timespan(1, 0), Poco::Net::WebSocket::SelectMode::SELECT_READ))
        {
            receive_buffer();
        }
    }

    ~PocoHelper()
    {
        m_psock->close();
        delete m_psock;
    }

    void send_buffer(char* buffer, unsigned int bufferLen)
    {
        try
        {
            if (msgSize <= 0 && m_psock->poll(Poco::Timespan(2, 0), Poco::Net::WebSocket::SelectMode::SELECT_WRITE))
            {
                msgSize = 8000;

                Buffer<char>* tempBuffer = container;
                int sent = m_psock->sendBytes(&tempBuffer, tempBuffer->sizeBytes(), WebSocket::FRAME_OP_SETRAW);

                logHelper.LogMessage("Sent bytes: " + std::to_string(sent));

                container = new Buffer<char>(msgSize);
            }

            if (m_psock->poll(Poco::Timespan(1, 0), Poco::Net::WebSocket::SelectMode::SELECT_READ))
            {
                receive_buffer();
            }

            if (*buffer)
            {
                container->append(buffer, bufferLen);
                msgSize -= bufferLen;
            }
        }
        catch (Poco::Net::WebSocketException ex)
        {
            switch (ex.code())
            {
            case WebSocket::ErrorCodes::WS_ERR_UNAUTHORIZED:
                logHelper.LogMessage("Unauthorized socket!");
                break;
            case WebSocket::ErrorCodes::WS_ERR_PAYLOAD_TOO_BIG:
                logHelper.LogMessage("Payload too big...");
            case WebSocket::ErrorCodes::WS_ERR_INCOMPLETE_FRAME:
                logHelper.LogMessage("Incomplete Frame");
                break;
            }

            string what(ex.message());

            if (!what.empty())
            {
                logHelper.LogMessage(what);
            }
        }
    }

    void receive_buffer()
    {
        try
        {
            char readMsg[256];
            int flags = 0;

            int rlen = m_psock->receiveFrame(&readMsg, 256, flags);
            logHelper.LogMessage(readMsg);
        }
        catch (Poco::Exception ex)
        {
            string msg(ex.what());
            logHelper.LogMessage("Exception: " + msg);
        }
    }

    void close() {
        try {
            m_psock->shutdown();
        }
        catch (...) {
            logHelper.LogMessage("closing failed.");
        }
    }
};

I am unable to send real time audio-raw (PCM) over websocket using above poco lib.


Solution

  • I have sorted that by changing sendBytes to sendFrame and things are working as expected. Thanks