123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- //
- // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/vinniefalco/CppCon2018
- //
- #include "websocket_session.hpp"
- #include <iostream>
- websocket_session::
- websocket_session(
- tcp::socket&& socket,
- boost::shared_ptr<shared_state> const& state)
- : ws_(std::move(socket))
- , state_(state)
- {
- }
- websocket_session::
- ~websocket_session()
- {
- // Remove this session from the list of active sessions
- state_->leave(this);
- }
- void
- websocket_session::
- fail(beast::error_code ec, char const* what)
- {
- // Don't report these
- if( ec == net::error::operation_aborted ||
- ec == websocket::error::closed)
- return;
- std::cerr << what << ": " << ec.message() << "\n";
- }
- void
- websocket_session::
- on_accept(beast::error_code ec)
- {
- // Handle the error, if any
- if(ec)
- return fail(ec, "accept");
- // Add this session to the list of active sessions
- state_->join(this);
- // Read a message
- ws_.async_read(
- buffer_,
- beast::bind_front_handler(
- &websocket_session::on_read,
- shared_from_this()));
- }
- void
- websocket_session::
- on_read(beast::error_code ec, std::size_t)
- {
- // Handle the error, if any
- if(ec)
- return fail(ec, "read");
- // Send to all connections
- state_->send(beast::buffers_to_string(buffer_.data()));
- // Clear the buffer
- buffer_.consume(buffer_.size());
- // Read another message
- ws_.async_read(
- buffer_,
- beast::bind_front_handler(
- &websocket_session::on_read,
- shared_from_this()));
- }
- void
- websocket_session::
- send(boost::shared_ptr<std::string const> const& ss)
- {
- // Post our work to the strand, this ensures
- // that the members of `this` will not be
- // accessed concurrently.
- net::post(
- ws_.get_executor(),
- beast::bind_front_handler(
- &websocket_session::on_send,
- shared_from_this(),
- ss));
- }
- void
- websocket_session::
- on_send(boost::shared_ptr<std::string const> const& ss)
- {
- // Always add to queue
- queue_.push_back(ss);
- // Are we already writing?
- if(queue_.size() > 1)
- return;
- // We are not currently writing, so send this immediately
- ws_.async_write(
- net::buffer(*queue_.front()),
- beast::bind_front_handler(
- &websocket_session::on_write,
- shared_from_this()));
- }
- void
- websocket_session::
- on_write(beast::error_code ec, std::size_t)
- {
- // Handle the error, if any
- if(ec)
- return fail(ec, "write");
- // Remove the string from the queue
- queue_.erase(queue_.begin());
- // Send the next message if any
- if(! queue_.empty())
- ws_.async_write(
- net::buffer(*queue_.front()),
- beast::bind_front_handler(
- &websocket_session::on_write,
- shared_from_this()));
- }
|