sourcey / libsourcey

C++14 evented IO libraries for high performance networking and media based applications
https://sourcey.com/libsourcey
GNU Lesser General Public License v2.1
1.31k stars 347 forks source link

Right way to write a SSL WebSocket server #220

Open biziosan opened 6 years ago

biziosan commented 6 years ago

Hi,

I am trying to use this awesome library to write a simple SSL Websocket server. However, I can't figure out from the examples how to create one. Can you suggest an example? Thanks!

My server always start accepting a connection, but it closes it right after. As a client I am using a simple Typescript I wrote:

       const WebSocket = require('ws');
       const ws = new WebSocket('wss://localhost:9009', {});
        ws.on('open', function open() {
            ws.send('something');
        });

        ws.on('message', function incoming(data) {
            console.log(data);
        });

The main class creates the socket and the adapter:

class Com
{
public:
    Com()
    {
        SSLManager::initNoVerifyServer();
    }

    ~Com()
    {
        SSLManager::instance().shutdown();
    }

    void start()
    {
        socket = std::make_shared<SSLSocket>(SSLManager::instance().defaultServerContext());
        adapter = std::make_shared<Prot>(socket, request, response);

        socket->bind(Address("0.0.0.0", 9009));
        socket->AcceptConnection += scy::slot(adapter.get(), &Prot::onAcceptConnection);
        socket->listen();

        scy::waitForShutdown();
    }

private:
    std::shared_ptr<Prot> adapter;

    typename http::Request request;
    typename http::Response response;

    typename SSLSocket::Ptr socket;
};

The adapter:

class Prot: public ws::WebSocketAdapter
{
public:
    Prot(const Socket::Ptr& socket, Request& request, Response response):
        ws::WebSocketAdapter(socket, ws::Mode::ServerSide, request, response)
    {}

    virtual ~Prot()
    {}

    void onAcceptConnection(const TCPSocket::Ptr& socket)
    {
        std::cout << "Attempting connection from " << socket->peerAddress().toString() << std::endl;
        socket->addReceiver(this);
    }

    void onSocketConnect(Socket& socket) override
    {
        std::cout << "socket connect" << std::endl;
    }

    void onSocketRecv(Socket& socket, const MutableBuffer& buffer, const Address& peerAddress) override
    {
        std::cout << "data received" << std::endl;
        std::string stringBuffer = std::string(scy::bufferCast<const char*>(buffer), buffer.size());
        std::cout << stringBuffer << std::endl;
    }

    void onSocketError(Socket& socket, const scy::Error& error) override
    {
        std::cout << error.message << std::endl;
    }

    void onSocketClose(Socket& socket) override
    {
        std::cout << "socket closed" << std::endl;
    }
};