]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/example/websocket/server/chat-multi/websocket_session.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / beast / example / websocket / server / chat-multi / websocket_session.cpp
1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/vinniefalco/CppCon2018
8 //
9
10 #include "websocket_session.hpp"
11 #include <iostream>
12
13 websocket_session::
14 websocket_session(
15 tcp::socket&& socket,
16 boost::shared_ptr<shared_state> const& state)
17 : ws_(std::move(socket))
18 , state_(state)
19 {
20 }
21
22 websocket_session::
23 ~websocket_session()
24 {
25 // Remove this session from the list of active sessions
26 state_->leave(this);
27 }
28
29 void
30 websocket_session::
31 fail(beast::error_code ec, char const* what)
32 {
33 // Don't report these
34 if( ec == net::error::operation_aborted ||
35 ec == websocket::error::closed)
36 return;
37
38 std::cerr << what << ": " << ec.message() << "\n";
39 }
40
41 void
42 websocket_session::
43 on_accept(beast::error_code ec)
44 {
45 // Handle the error, if any
46 if(ec)
47 return fail(ec, "accept");
48
49 // Add this session to the list of active sessions
50 state_->join(this);
51
52 // Read a message
53 ws_.async_read(
54 buffer_,
55 beast::bind_front_handler(
56 &websocket_session::on_read,
57 shared_from_this()));
58 }
59
60 void
61 websocket_session::
62 on_read(beast::error_code ec, std::size_t)
63 {
64 // Handle the error, if any
65 if(ec)
66 return fail(ec, "read");
67
68 // Send to all connections
69 state_->send(beast::buffers_to_string(buffer_.data()));
70
71 // Clear the buffer
72 buffer_.consume(buffer_.size());
73
74 // Read another message
75 ws_.async_read(
76 buffer_,
77 beast::bind_front_handler(
78 &websocket_session::on_read,
79 shared_from_this()));
80 }
81
82 void
83 websocket_session::
84 send(boost::shared_ptr<std::string const> const& ss)
85 {
86 // Post our work to the strand, this ensures
87 // that the members of `this` will not be
88 // accessed concurrently.
89
90 net::post(
91 ws_.get_executor(),
92 beast::bind_front_handler(
93 &websocket_session::on_send,
94 shared_from_this(),
95 ss));
96 }
97
98 void
99 websocket_session::
100 on_send(boost::shared_ptr<std::string const> const& ss)
101 {
102 // Always add to queue
103 queue_.push_back(ss);
104
105 // Are we already writing?
106 if(queue_.size() > 1)
107 return;
108
109 // We are not currently writing, so send this immediately
110 ws_.async_write(
111 net::buffer(*queue_.front()),
112 beast::bind_front_handler(
113 &websocket_session::on_write,
114 shared_from_this()));
115 }
116
117 void
118 websocket_session::
119 on_write(beast::error_code ec, std::size_t)
120 {
121 // Handle the error, if any
122 if(ec)
123 return fail(ec, "write");
124
125 // Remove the string from the queue
126 queue_.erase(queue_.begin());
127
128 // Send the next message if any
129 if(! queue_.empty())
130 ws_.async_write(
131 net::buffer(*queue_.front()),
132 beast::bind_front_handler(
133 &websocket_session::on_write,
134 shared_from_this()));
135 }