0 / 0 / 0
Регистрация: 06.12.2018
Сообщений: 3
1

Подключение к websockets + SSL и удержание соединения

06.12.2018, 14:05. Показов 5478. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Беда с boost и асинхронными websockets. Прошу сильно не ругать, это мой первый пост.
Постараюсь изложить мою мысль правильно.

Я хочу подключиться к бирже и читать не прерывно котировки.
Исходя из примера ссылка я подписываюсь на канал и слушаю. Я даже иногда вижу данные, но чаще вот такую ошибку "read: The WebSocket stream was gracefully closed at both endpoints". Программа завершается в любом случае, попали туда данные или нет. А мне нужно чтобы он читал не прерывно. Как мне такое сделать ?


компилирую на Debian так
Bash
1
g++ test.cpp -o testbin -std=c++11 -lcrypto -lssl -lboost_system-mt -lboost_thread-mt -lpthread
вот сам код

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
 
namespace beast = boost::beast;
namespace http = beast::http;
namespace websocket = beast::websocket;
namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
using tcp = boost::asio::ip::tcp;
 
void
fail(beast::error_code ec, char const* what)
{
    std::cerr << what << ": " << ec.message() << "\n";
}
 
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:
    explicit
    session(net::io_context& ioc, ssl::context& ctx)
        : resolver_(ioc)
        , ws_(ioc, ctx)
    {
    }
 
    void
    run(
        char const* host,
        char const* port,
        char const* text)
    {
        host_ = host;
        text_ = text;
 
        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");
 
        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");
 
        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");
 
        ws_.async_handshake(host_, text_,
            std::bind(
                &session::on_handshake,
                shared_from_this(),
                std::placeholders::_1));
    }
 
    void
    on_handshake(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "handshake");
        
        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");
        
        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");
 
        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");
 
        std::cout << beast::buffers(buffer_.data()) << std::endl;
    }
};
 
//------------------------------------------------------------------------------
 
int main(int argc, char** argv)
{
    auto const host = "stream.binance.com";
    auto const port = "9443";
    auto const text = "/ws/ethbtc@kline_1m";
 
    net::io_context ioc;
    ssl::context ctx{ssl::context::sslv23_client};
    ctx.set_verify_mode(ssl::verify_none);
    std::make_shared<session>(ioc, ctx)->run(host, port, text);
    ioc.run();
 
    return EXIT_SUCCESS;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.12.2018, 14:05
Ответы с готовыми решениями:

Считать данные из ssl соединения
Здравствуйте. Есть демон, который висит на машине и слушает определенный порт. При обращении к...

Ssl Сервер и входящие соединения
Использую стандартный код для поднятия сокет-ssl-сервера: SSLServerSocketFactory ssf =...

PHP подключение к google.com через ssl
$sock = fsockopen(&quot;ssl://google.com&quot;, 443, $errno, $errstr, 30); if (!$sock) die(&quot;$errstr...

подключение коммутируемого соединения
Когда какая нибудь программа лезет в инет(аська, скайп, гаджеты на рабочем столе) то вылезает такая...

1
0 / 0 / 0
Регистрация: 23.08.2018
Сообщений: 5
13.06.2023, 21:40 2
Наверное уже не актуально)) Но причина в собственноручном закрытии сокета после чтения:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 void
    on_read(
        beast::error_code ec,
        std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);
 
        if(ec)
            return fail(ec, "read");
 
       [COLOR="Red"] ws_.async_close(websocket::close_code::normal,
            std::bind(
                &session::on_close,
                shared_from_this(),
                std::placeholders::_1));[/COLOR]
    }
Вместо закрытия надо просто сделать повторное чтение - тогда оно зациклится.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 void
    on_read(
        beast::error_code ec,
        std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);
 
        if(ec)
            return fail(ec, "read");
 
       ws_.async_read(
            buffer_,
            std::bind(
                &session::on_read,
                shared_from_this(),
                std::placeholders::_1,
                std::placeholders::_2));
    }
0
13.06.2023, 21:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.06.2023, 21:40
Помогаю со студенческими работами здесь

Sql server 2008r2. Ole db подключение выдает ошибку ssl
В реестре выставлял сертификат равный нулю. Tsl 1.2 включен. Драйвер ole db обновлял. В менеджер...

Не получается создать SSL подключение к Bitstamp на java на протоколе Fix
Всем привет! Возникла проблема при подключении к Bitstamp для получения мгновенной информации с...

Настроить автоматическое подключение сетевого соединения
Вообщем недавно собрал gentoo. Вот какая проблема. Приходится каждый раз вводить: ifconfig enp0s3...

Как сделать автоматическое подключение проводного соединения?
Вчера впервые поставил себе Linux (Ubuntu 13.10). Когда зашел - интернета не было. В трее зашел в...

Повторное подключение к серверу БД MS SQL при разрыве соединения
Доброго времени суток! У меня возникла задача реализовать переподключение клиента к серверу БД в...

Автоматическое подключение к серверу после разрыва соединения с ним
Собственно, сабж. Пока ползал по форуму, пофиксил некоторые недочёты, но проблема осталась...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru