'ssl_socket cannot convert from '_Ty' to 'ssl::stream<asio::ip::tcp::socket>'
i was following a javid tutorial about networking and websockets with boost Asio
I've made cool progress but was stuck on securing the websocket connection using ssl
Here's what I made so far Note: I will shorten my 3000 long lines of code to something more digestible
first the includes
#include <boost/asio.hpp>
#include <boost/asio/ts/buffer.hpp>
#include <boost/asio/ts/internet.hpp>
#include <boost/asio/ssl.hpp>
using namespace boost;
namespace ssl = boost::asio::ssl;
typedef ssl::stream<asio::ip::tcp::socket> ssl_socket;
After these includes and typedefs Comes the connection class
template<typename T>
class connection;
template<typename T>
class connection : public std::enable_shared_from_this<connection<T>>
{
public:
enum class owner
{
server,
client
};
public:
connection(owner parent, asio::io_context& asioContext, ssl_socket socket, tsqueue<owned_message<T>>& qIn)
: m_asioContext(asioContext), m_socket(std::move(socket)), m_qMessagesIn(qIn)
{
m_nOwnerType = parent;
// Construct validation check data
if (m_nOwnerType == owner::server)
{
m_nHandshakeOut = uint64_t(std::chrono::system_clock::now().time_since_epoch().count());
m_nHandshakeCheck = scramble(m_nHandshakeOut);
}
else
{
m_nHandshakeIn = 0;
m_nHandshakeOut = 0;
}
}
...
protected:
// Each connection has a unique socket to a remote
ssl_socket m_socket;
And i'm creating this connection class this way
bool Connect(const std::string& host, const uint16_t port)
{
try
{
ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();
asio::ip::tcp::resolver resolver(m_context);
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, std::to_string(port));
m_connection = std::make_unique<connection<T>>(connection<T>::owner::client, m_context, ssl_socket(m_context, ctx), m_qMessagesIn);
m_connection->ConnectToServer(endpoints);
thrContext = std::thread([this]() { m_context.run(); });
}
catch (std::exception& e)
{
std::cerr << "[ASIO] Client Exception: " << e.what() << "\n";
return false;
}
return true;
}
Problem is i get an error when i try to compile my code Error says:
D:\Microsoft Visual Studio 2022\VC\Tools\MSVC\14.30.30705\include\xutility(149,56): error C2664: 'olc::net::connection<T>::connection(olc::net::connection<T>::owner,boost::asio::io_context &,ssl_socket,olc::net::tsqueue<olc::net::owned_message<T>> &)': cannot convert argument 3 from '_Ty' to 'ssl_socket'
with
[
T=GameMsg
]
and
[
_Ty=boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::any_io_executor>
] (compiling source file ..\..\Classes\EmptyScene.cpp)
D:\Microsoft Visual Studio 2022\VC\Tools\MSVC\14.30.30705\include\xutility(149,77): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called (compiling source file ..\..\Classes\EmptyScene.cpp)
I'm quite a noob in these C++ type things From my understanding is that it cannot convert to T But how can I that when I need T to be asio::ip::tcp::socket like in ssl_socket typedef?
Solution 1:[1]
the basic_stream_socket doesn't have a copyable constructor, it has a movable constructor instead of, which means that you must move the socket instance instead of copy it:
For example, I'm using streams that are built from a socket, which needs to receive the whole socket instead of copying it:
class wscnx : public std::enable_shared_from_this<wscnx>, public jomt::connection
{
using t_ws_ssl = boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::tcp_stream>>;
std::unique_ptr<t_ws_ssl> m_wss;
//...
public:
wscnx(boost::asio::ip::tcp::socket &&sck, boost::asio::ssl::context &cnx,
//...
};
wscnx::wscnx(boost::asio::ip::tcp::socket &&sck, boost::asio::ssl::context &cntx,
std::shared_ptr<wsserver> server) :m_wss(new t_ws_ssl(std::move(sck), cntx))
{
//...
}
In the previous sample, the semantic of the constructor wscnx is for moveable, in the case of boost::asio::ip::tcp::socket &&sck, in this way you need to use the function std::move to transfer the instance instead of copying it, so when the program gets the socket instance, you need to move it into the stream, as the sample below shows:
boost::asio::ip::tcp::socket socket
// Create the instance of the socket
// Move the instance of the socket into the constructor
std::shared_ptr<wscnx> cnx = std::make_shared<wscnx>(std::move(socket), std::ref(m_ssl_ioc), shared_from_this());
The instruction std::move(socket)move the instance of wscnx which will allocate the instance of socket into its stream m_wss that is created int he constructor with another move instruction: m_wss(new t_ws_ssl(std::move(sck), cnx)) where t_ws_ssl is an alias for boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::tcp_stream>>
I hope it could help you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jorge Omar Medra |
