Как отправлять и получать сообщения с помощью websocket websocketpp? - PullRequest
1 голос
/ 07 мая 2020

Как отправлять и получать сообщения с помощью websocket websocketpp?

У меня есть небольшой код в C ++, и я пытаюсь использовать websocketpp lib

Я использую пример клиента / сервера доступен, но терминал показывает только то, что он был подключен.

https://github.com/zaphoyd/websocketpp

Я новичок в C ++ поэтому я ценю внимание, которое могу помочь. Потому что я изучаю язык и технологию websocket.

Сервер

#include <iostream>
// WebService
#include <set>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <functional>


typedef websocketpp::server<websocketpp::config::asio> server;

class utility_server {
public:
    utility_server() {
        // Set logging settings
        m_endpoint.set_error_channels(websocketpp::log::elevel::all);
        m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload);

        // Initialize Asio
        m_endpoint.init_asio();

        // Set the default message handler to the echo handler
        m_endpoint.set_message_handler(std::bind(
            &utility_server::echo_handler, this,
            std::placeholders::_1, std::placeholders::_2
        ));
    }

    void echo_handler(websocketpp::connection_hdl hdl, server::message_ptr msg) {
        // write a new message
        m_endpoint.send(hdl, msg->get_payload(), msg->get_opcode());
    }

    void run() {
        // Listen on port 9002
        m_endpoint.listen(9002);

        // Queues a connection accept operation
        m_endpoint.start_accept();

        // Start the Asio io_service run loop
        m_endpoint.run();
    }
private:
    server m_endpoint;
};

int main()
{
    utility_server s;
    s.run();
    return 0;
}

Клиент

#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>

#include <iostream>

typedef websocketpp::client<websocketpp::config::asio_client> client;

using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

// pull out the type of messages sent by our config
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;

// This message handler will be invoked once for each incoming message. It
// prints the message and then sends a copy of the message back to the server.
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
    std::cout << "on_message called with hdl: " << hdl.lock().get()
        << " and message: " << msg->get_payload()
        << std::endl;


    websocketpp::lib::error_code ec;

    c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
    if (ec) {
        std::cout << "Echo failed because: " << ec.message() << std::endl;
    }
}

int main(int argc, char* argv[]) {
    // Create a client endpoint
    client c;

    std::string uri = "ws://localhost:9002";

    if (argc == 2) {
        uri = argv[1];
    }

    try {
        // Set logging to be pretty verbose (everything except message payloads)
        c.set_access_channels(websocketpp::log::alevel::all);
        c.clear_access_channels(websocketpp::log::alevel::frame_payload);

        // Initialize ASIO
        c.init_asio();

        // Register our message handler
        c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));

        websocketpp::lib::error_code ec;
        client::connection_ptr con = c.get_connection(uri, ec);
        if (ec) {
            std::cout << "could not create connection because: " << ec.message() << std::endl;
            return 0;
        }

        // Note that connect here only requests a connection. No network messages are
        // exchanged until the event loop starts running in the next line.
        c.connect(con);

        // Start the ASIO io_service run loop
        // this will cause a single connection to be made to the server. c.run()
        // will exit when this connection is closed.
        c.run();
    }
    catch (websocketpp::exception const& e) {
        std::cout << e.what() << std::endl;
    }
}

1 Ответ

0 голосов
/ 24 мая 2020

Вам необходимо вызвать метод send (), используя экземпляр клиента; различные перегрузки задокументированы здесь . РЕДАКТИРОВАТЬ: Я вижу, что вы уже звоните, но не в том месте. Поскольку он находится в обработчике сообщений on, он будет отправлять только при получении сообщения. И код сервера сам по себе не отправляет никаких сообщений, поэтому отправка в клиенте никогда не сработает. Пример websocketpp помещает send в открытый обработчик, но помимо демонстрации это довольно бесполезный вариант использования.

Чаще всего вы хотите вызывать send прямо из кода вашего приложения. Сложность заключается в том, как согласовать тот факт, что вам нужно вызвать run (), прежде чем вы сможете что-либо делать с клиентом, а run - это блокирующий вызов (что означает, что вы не можете вызывать send после). Ответ на это - иметь один поток, предназначенный для вызова run (), который позволяет вам вызывать send () в основном потоке (или в любом другом потоке, который вы хотите).

Поскольку вы говорите, что вы новичок в C ++ Я бы посоветовал сначала изучить потоки: узнать, как их запускать и корректно останавливать, а также узнать о безопасности потоков. Есть несколько способов использовать потоки в C ++, но в этом случае я бы рекомендовал взглянуть на std :: thread.

Как только вы поймете, как использовать потоки в C ++, попробуйте встроить это в свое приложение . В конце концов, было бы неплохо создать класс для вашего клиента, который имеет дело с потоком и отправкой сообщений et c.

Как только вы получите что-то работающее, я бы рекомендовал прочитать websocketpp FAQ) , в частности, раздел «Как полностью выйти из программы на основе транспорта Asio».

...