| 194 | } |
| 195 | |
| 196 | void read_line() |
| 197 | { |
| 198 | // Set a deadline for the read operation. |
| 199 | input_deadline_.expires_after(std::chrono::seconds(30)); |
| 200 | |
| 201 | // Start an asynchronous operation to read a newline-delimited message. |
| 202 | auto self(shared_from_this()); |
| 203 | boost::asio::async_read_until(socket_, |
| 204 | boost::asio::dynamic_buffer(input_buffer_), '\n', |
| 205 | [this, self](const boost::system::error_code& error, std::size_t n) |
| 206 | { |
| 207 | // Check if the session was stopped while the operation was pending. |
| 208 | if (stopped()) |
| 209 | return; |
| 210 | |
| 211 | if (!error) |
| 212 | { |
| 213 | // Extract the newline-delimited message from the buffer. |
| 214 | std::string msg(input_buffer_.substr(0, n - 1)); |
| 215 | input_buffer_.erase(0, n); |
| 216 | |
| 217 | if (!msg.empty()) |
| 218 | { |
| 219 | channel_.deliver(msg); |
| 220 | } |
| 221 | else |
| 222 | { |
| 223 | |
| 224 | // We received a heartbeat message from the client. If there's |
| 225 | // nothing else being sent or ready to be sent, send a heartbeat |
| 226 | // right back. |
| 227 | if (output_queue_.empty()) |
| 228 | { |
| 229 | output_queue_.push_back("\n"); |
| 230 | |
| 231 | // Signal that the output queue contains messages. Modifying |
| 232 | // the expiry will wake the output actor, if it is waiting on |
| 233 | // the timer. |
| 234 | non_empty_output_queue_.expires_at( |
| 235 | steady_timer::time_point::min()); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | read_line(); |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | stop(); |
| 244 | } |
| 245 | }); |
| 246 | } |
| 247 | |
| 248 | void await_output() |
| 249 | { |
nothing calls this directly
no test coverage detected