如何连接到"wss"上的特定端点. [IBM Watson] [英] How to connect to particular endpoint on "wss" [IBM Watson]

查看:150
本文介绍了如何连接到"wss"上的特定端点. [IBM Watson]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用boost库连接到IBM Web服务器(语音到文本).

I am using the boost library to connect to IBM web-server (speech to text).

而且我处于网络套接字握手阶段.代码.我已经提到网络套接字异步SSL客户端示例.

And I am stuck at web-socket handshaking stage. of the code. I have referred to the Web-socket async SSL client example.

这是代码(类似于上面的示例,其中有一些调试cout):目标是连接到wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?apikey={my apikey}

// Report a failure
void
fail(beast::error_code ec, char const* what)
{
    std::cerr << what << ": " << ec.message() << "\n";
}

// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
    tcp::resolver resolver_;
    websocket::stream<ssl::stream<tcp::socket>> ws_;
    beast::multi_buffer buffer_;
    std::string host_;
    std::string text_;

public:
    // Resolver and socket require an io_context
    explicit
    session(net::io_context& ioc, ssl::context& ctx)
        : resolver_(ioc)
        , ws_(ioc, ctx)
    {
    }

    // Start the asynchronous operation
    void run(char const* host, char const* port, char const* text)
    {
        // Save these for later
        host_ = host;
        text_ = text;

        std::cout<< "Successfully reached: run operation:" << __LINE__<<" Resolving"<<std::endl;
        // Look up the domain name
        resolver_.async_resolve(
            host,
            port,
            std::bind(&session::on_resolve, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
    }

    void on_resolve(beast::error_code ec, tcp::resolver::results_type results)
    {
        if(ec)
            return fail(ec, "resolve");

        std::cout<< "Successfully reached: resolve operation:" << __LINE__<<" Resolving"<<std::endl;
        // Make the connection on the IP address we get from a lookup
        net::async_connect(
            ws_.next_layer().next_layer(),
            results.begin(),
            results.end(),
            std::bind(&session::on_connect, shared_from_this(), std::placeholders::_1));
    }

    void on_connect(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "connect");

        std::cout<< "Successfully reached: handshaking operation:" << __LINE__<<" Handshaking"<<std::endl;
        // Perform the SSL handshake
        ws_.next_layer().async_handshake(ssl::stream_base::client, std::bind(&session::on_ssl_handshake, shared_from_this(), std::placeholders::_1));
    }

    void on_ssl_handshake(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "ssl_handshake");

        std::cout<< "Successfully reached: handshaking operation:" << __LINE__<<" Handshaking"<<std::endl;
        // Perform the websocket handshake
        ws_.async_handshake(host_, "/speech-to-text/api/v1/recognize", std::bind( &session::on_handshake, shared_from_this(), std::placeholders::_1));
    }

    void on_handshake(beast::error_code ec)
    {
        std::cout<< "Successfully reached: handshaking operation:" << __LINE__<<" Handshaking"<<std::endl;
        if(ec)
            return fail(ec, "handshake");

        std::cout<< "Successfully reached: handshaking operation:" << __LINE__<<" Send message"<<std::endl;
        // Send the message
        ws_.async_write(net::buffer(text_), std::bind(&session::on_write, shared_from_this(), std::placeholders::_1,
                                                                                            std::placeholders::_2));
    }

    void
    on_write(
        beast::error_code ec,
        std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);

        if(ec)
            return fail(ec, "write");

        // Read a message into our buffer
        ws_.async_read(
            buffer_,
            std::bind(
                &session::on_read,
                shared_from_this(),
                std::placeholders::_1,
                std::placeholders::_2));
    }

    void
    on_read(
        beast::error_code ec,
        std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);

        if(ec)
            return fail(ec, "read");

        // Close the WebSocket connection
        ws_.async_close(websocket::close_code::normal,
            std::bind(
                &session::on_close,
                shared_from_this(),
                std::placeholders::_1));
    }

    void
    on_close(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "close");

        // If we get here then the connection is closed gracefully

        // The buffers() function helps print a ConstBufferSequence
        std::cout << beast::buffers(buffer_.data()) << std::endl;
    }
};

//------------------------------------------------------------------------------

int main(int argc, char** argv)
{
    auto const host = "stream.watsonplatform.net";
    auto const port = "443";
    auto const text = "speech-to-text/api/v1/recognize";//apikey={my apikey}

    std::cout<< "Successfully reached: Main function"<<std::endl;
    // The io_context is required for all I/O
    net::io_context ioc;

    // The SSL context is required, and holds certificates
    ssl::context ctx{ssl::context::sslv23_client};
    std::cout<< "Successfully reached: SSL context to hold certificates"<<std::endl;

    // This holds the root certificate used for verification
    load_root_certificates(ctx);

    std::cout<< "Successfully reached: Loading root certificates - Goes to Launch asyn operation"<<std::endl;
    // Launch the asynchronous operation
    std::make_shared<session>(ioc, ctx)->run(host, port, text);

    std::cout<< "Successfully reached: Launched asyn operation"<<std::endl;
    // Run the I/O service. The call will return when
    // the socket is closed.
    ioc.run();

    return EXIT_SUCCESS;
}

我在控制台上得到的输出为:

I am getting the output on console as :

成功达到:主要功能

Successfully reached: Main function

成功达到:用于保存证书的SSL上下文

Successfully reached: SSL context to hold certificates

成功达成:加载根证书-进入启动asyn 操作

Successfully reached: Loading root certificates - Goes to Launch asyn operation

成功达成:运行操作:71正在解决

Successfully reached: run operation:71 Resolving

成功达成:启动了异步操作

Successfully reached: Launched asyn operation

成功达成:解决操作:84解决

Successfully reached: resolve operation:84 Resolving

成功达成:握手操作:98次握手

Successfully reached: handshaking operation:98 Handshaking

成功达成:握手操作:108次握手

Successfully reached: handshaking operation:108 Handshaking

成功达成:握手操作:115次握手

Successfully reached: handshaking operation:115 Handshaking

握手:远程对等方拒绝了WebSocket握手

handshake: The WebSocket handshake was declined by the remote peer

在这里我很困惑哪里发生了错误 on_ssl_handshake on_handshake ,以及如何完成上述目标".

Here I am A bit confused where the error has occured on_ssl_handshake or on_handshake and how to accomplish the above "Aim".

请提供解决方案.

致谢

Wireshark条目:

Wireshark entries:

推荐答案

哦,它起作用了!

问题出在ws_.async_handshake上,而我不得不使用ws_.async_handshake_ex如下:

the problem was with the ws_.async_handshake instead I had to use the ws_.async_handshake_ex as below:

ws_.async_handshake_ex(host_, "/speech-to-text/api/v1/recognize",[](request_type& reqHead){reqHead.insert(http::field::authorization,"Bearer {my token}");},std::bind( &session::on_handshake, shared_from_this(), std::placeholders::_1));

tokenapikey不同.它需要按照中的给出的方式生成

The token is not the same as apikey. It needs to be generated as given in this post

说明:

网址是"stream.watsonplatform.net/speech-to-text/api/v1/recognize" 然后authentication token作为请求标头.

The url is "stream.watsonplatform.net/speech-to-text/api/v1/recognize" and the authentication token goes as request header.

这篇关于如何连接到"wss"上的特定端点. [IBM Watson]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆