Home > Mobile >  Using websocketspp to connect to free remote server on the Render hosting
Using websocketspp to connect to free remote server on the Render hosting

Time:10-07

I'm using Windows 10, MinGW 64-bit. I'm trying to connect to my server (see my server script below) which is hosted on the Render hosting at this address:

std::string uri = "wss://connection-js.onrender.com";

When I use "wss://..." I see this error: could not create connection because: endpoint not secure. But when I use "ws://..." I see these errors:

[2022-10-07 00:33:09] [connect] Successful connection
[2022-10-07 00:33:09] [error] Server handshake response error: websocketpp.processor:20 (Invalid HTTP status.)
[2022-10-07 00:33:09] [fail] WebSocket Connection 216.24.57.3:80 - "WebSocket  /0.8.2" / 301 websocketpp.processor:20 Invalid HTTP status.

But this works locally:

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

I tried to connect my Qt6 client to this server - it works for "wss://..." but does not work for "ws://...".

main.cpp

#define ASIO_STANDALONE
#define _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
#define _WEBSOCKETPP_CPP11_STRICT_
#define _WEBSOCKETPP_CPP11_TYPE_TRAITS_

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

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()
{
    // Create a client endpoint
    client c;

    // std::string uri = "ws://localhost:3000";
    std::string uri = "wss://connection-js.onrender.com";

    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;
    }

    return 0;
}

makefile

CC = g  

INC = -I"E:\Libs\websocketpp-0.8.2-headers" \
      -I"E:\Libs\asio-1.24.0\include"

all: main.o
    $(CC) main.o -lws2_32 -o app

main.o: main.cpp
    $(CC) -c $(INC) main.cpp -o main.o

Server:

const express = require("express");
const http = require("http");
const ws = require("ws");
const path = require("path");

const app = express();
app.use(express.static(path.join(process.cwd(), "public")));

const httpServer = http.createServer(app);
const wss = new ws.Server(
{
    server: httpServer
});

const port = process.env.PORT || 3000;
httpServer.listen(port, () => console.log("Listening at port: "   port));

wss.on("connection", socket =>
{
    console.log("client was connected");
});

This is the Qt client that works:

main.cpp

#include <QtCore/QDebug>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWebSockets/QWebSocket>

class Window : public QWidget
{
    Q_OBJECT

private:
    QWebSocket m_webSocket;

public:
    Window(QWidget *parent = nullptr)
        : QWidget(parent)
    {
        setWindowTitle("Qt6 C   Client");
        resize(300, 300);

        connect(&m_webSocket, &QWebSocket::connected,
            this, &Window::onConnected);
        // m_webSocket.open(QUrl("ws://localhost:3000"));
        m_webSocket.open(QUrl("wss://connection-js.onrender.com"));
        qDebug() << "Waiting for connection...";
    }

private slots:

    void onConnected()
    {
        qDebug() << "Client was connected to server";
    }
};

#include "main.moc"

#ifdef _WIN32
#include <Windows.h>
#endif

int main(int argc, char *argv[])
{
#ifdef _WIN32
    if (AttachConsole(ATTACH_PARENT_PROCESS))
    {
        freopen("CONOUT$", "w", stdout);
        freopen("CONOUT$", "w", stderr);
    }
#endif

    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}

websocket-client-qt6-cpp.pro

# Build commands for CMD:
# qmake -makefile
# mingw32-make
# "./release/app"
 
QT  = core gui widgets websockets

CONFIG  = c  11
CONFIG  = console
 
SOURCES  = \
    main.cpp
 
TARGET = app

CodePudding user response:

The error 'endpoint not secure' means the client instance is not one for TLS(endpoint is the base class of the client class).

So, use the configuration websocketpp::config::asio_tls_client instead of the websocketpp::config::asio_client. Also see the official sample, print_client_tls.cpp.

  • Related