eris  1.4.0
A WorldForge client library.
StreamSocket.cpp
1 /*
2  Copyright (C) 2014 Erik Ogenvik
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software Foundation,
16  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include "StreamSocket.h"
24 #include "Log.h"
25 
26 #include <Atlas/Codec.h>
27 #include <Atlas/Net/Stream.h>
28 #include <Atlas/Objects/Encoder.h>
29 
30 using namespace boost::asio;
31 
32 static const int NEGOTIATE_TIMEOUT_SECONDS = 5;
33 
34 namespace Eris {
35 
36 StreamSocket::StreamSocket(io_service& io_service,
37  const std::string& client_name,
38  Atlas::Bridge& bridge,
39  Callbacks callbacks) :
40  m_io_service(io_service),
41  _bridge(bridge),
42  _callbacks(std::move(callbacks)),
43  mWriteBuffer(new boost::asio::streambuf()),
44  mSendBuffer(new boost::asio::streambuf()),
45  mInStream(&mReadBuffer),
46  mOutStream(mWriteBuffer.get()),
47  mShouldSend(false),
48  mIsSending(false),
49  _sc(new Atlas::Net::StreamConnect(client_name, mInStream, mOutStream)),
50  _negotiateTimer(io_service), _connectTimer(io_service),
51  m_codec(nullptr),
52  m_encoder(nullptr),
53  m_is_connected(false) {
54 }
55 
56 StreamSocket::~StreamSocket() = default;
57 
58 void StreamSocket::detach() {
59  _callbacks = Callbacks();
60 }
61 
62 void StreamSocket::startNegotiation() {
63  auto self(this->shared_from_this());
64  _negotiateTimer.expires_from_now(
65  std::chrono::seconds(NEGOTIATE_TIMEOUT_SECONDS));
66  _negotiateTimer.async_wait([this, self](const boost::system::error_code& ec) {
67  //If the negotiator still exists after the deadline it means that the negotation hasn't
68  //completed yet; we'll consider that a "timeout".
69  if (_sc != nullptr) {
70  if (_callbacks.stateChanged) {
71  debug() << "Client disconnected because of negotiation timeout.";
72 // log(NOTICE, "Client disconnected because of negotiation timeout.");
73  _callbacks.stateChanged(DISCONNECTING);
74 // mSocket.close();
75  }
76  }
77  });
78  _callbacks.stateChanged(NEGOTIATE);
79 
80  _sc->poll();
81 
82  write();
83  negotiate_read();
84 }
85 
86 Atlas::Negotiate::State StreamSocket::negotiate() {
87  // poll and check if negotiation is complete
88  _sc->poll();
89 
90  if (_sc->getState() == Atlas::Negotiate::IN_PROGRESS) {
91  return _sc->getState();
92  }
93 
94  // Check if negotiation failed
95  if (_sc->getState() == Atlas::Negotiate::FAILED) {
96  return _sc->getState();
97  }
98  // Negotiation was successful
99 
100  _negotiateTimer.cancel();
101 
102  // Get the codec that negotiation established
103  m_codec = _sc->getCodec(_bridge);
104 
105  // Acceptor is now finished with
106  _sc.reset();
107 
108  if (m_codec == nullptr) {
109  error() << "Could not create codec during negotiation.";
110  return Atlas::Negotiate::FAILED;
111  }
112  // Create a new encoder to send high level objects to the codec
113  m_encoder = std::make_unique<Atlas::Objects::ObjectsEncoder>(*m_codec);
114 
115  // This should always be sent at the beginning of a session
116  m_codec->streamBegin();
117 
118  _callbacks.stateChanged(CONNECTED);
119 
120  return Atlas::Negotiate::SUCCEEDED;
121 }
122 
123 Atlas::Codec& StreamSocket::getCodec() {
124  assert(m_codec);
125  return *m_codec;
126 }
127 
128 Atlas::Objects::ObjectsEncoder& StreamSocket::getEncoder() {
129  assert(m_encoder);
130  return *m_encoder;
131 }
132 
133 }
Definition: Account.cpp:33
Methods that are used as callbacks.
Definition: StreamSocket.h:77