ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/backend/communicator/asio_communicator.cpp
Revision: 1.2
Committed: Sun Oct 24 20:31:49 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
State: FILE REMOVED
Log Message:
use EV and plain sockets instead of asio

File Contents

# Content
1 #include "deliantra/asio_communicator.h"
2
3 #include <boost/asio/read.hpp>
4 #include <boost/asio/write.hpp>
5 #include <boost/asio/placeholders.hpp>
6
7 #include <boost/bind.hpp>
8
9 void
10 asio_communicator::receive ()
11 {
12 read_msg ();
13 }
14
15 void
16 asio_communicator::send (std::string const &command)
17 {
18 m_request.clear ();
19 m_request.push_back ((command.length () & 0xff00) >> 8 * 1);
20 m_request.push_back ((command.length () & 0x00ff) >> 8 * 0);
21 m_request.insert (m_request.end (), command.begin (), command.end ());
22 boost::asio::async_write (m_socket,
23 boost::asio::buffer (m_request),
24 boost::bind (&asio_communicator::handle_send, this,
25 boost::asio::placeholders::error,
26 boost::asio::placeholders::bytes_transferred));
27 }
28
29
30 void
31 asio_communicator::set_packet_handler (interface::packet_handler &handler)
32 {
33 on = &handler;
34 }
35
36 asio_communicator::asio_communicator ( boost::asio::io_service &io_service
37 , std::string const &server
38 , std::string const &port
39 )
40 : m_resolver (io_service)
41 , m_socket (io_service)
42 {
43 /*
44 * Start an asynchronous resolve to translate the server and service names
45 * into a list of endpoints.
46 */
47 tcp::resolver::query query (server, port);
48 m_resolver.async_resolve (query,
49 boost::bind (&asio_communicator::handle_resolve, this,
50 boost::asio::placeholders::error,
51 boost::asio::placeholders::iterator));
52 }
53
54 void
55 asio_communicator::handle_resolve ( boost::system::error_code const &err
56 , tcp::resolver::iterator endpoint_iterator
57 )
58 {
59 if (!err)
60 {
61 /*
62 * Attempt a connection to the first endpoint in the list. Each endpoint
63 * will be tried until we successfully establish a connection.
64 */
65 tcp::endpoint endpoint = *endpoint_iterator;
66 m_socket.async_connect (endpoint,
67 boost::bind (&asio_communicator::handle_connect, this,
68 boost::asio::placeholders::error,
69 ++endpoint_iterator));
70 }
71 else
72 throw std::runtime_error (std::string (__func__) + ": " + err.message ());
73 }
74
75 void
76 asio_communicator::handle_connect ( boost::system::error_code const &err
77 , tcp::resolver::iterator endpoint_iterator
78 )
79 {
80 if (!err)
81 on->ready ();
82 else if (endpoint_iterator != tcp::resolver::iterator ())
83 {
84 /* The connection failed. Try the next endpoint in the list. */
85 m_socket.close ();
86 tcp::endpoint endpoint = *endpoint_iterator;
87 m_socket.async_connect (endpoint,
88 boost::bind (&asio_communicator::handle_connect, this,
89 boost::asio::placeholders::error,
90 ++endpoint_iterator));
91 }
92 else
93 throw std::runtime_error (std::string (__func__) + ": " + err.message ());
94 }
95
96 void
97 asio_communicator::handle_send ( boost::system::error_code const &err
98 , size_t n
99 )
100 {
101 if (err)
102 throw std::runtime_error (std::string (__func__) + ": " + err.message ());
103 }
104
105 void
106 asio_communicator::read (void (asio_communicator::*handler) (boost::system::error_code const &err, size_t n), size_t length)
107 {
108 m_response.resize (length);
109 boost::asio::async_read (m_socket,
110 boost::asio::buffer (m_response),
111 boost::bind (handler, this,
112 boost::asio::placeholders::error,
113 boost::asio::placeholders::bytes_transferred));
114 }
115
116 void
117 asio_communicator::read_msg ()
118 {
119 read (&asio_communicator::read_msg_length, 2);
120 }
121
122 void
123 asio_communicator::read_msg_length (boost::system::error_code const &err, size_t n)
124 {
125 if (!err)
126 {
127 size_t length
128 = m_response.at (0) << 8 * 1
129 | m_response.at (1) << 8 * 0
130 ;
131 read (&asio_communicator::read_msg_body, length);
132 }
133 else
134 throw std::runtime_error (std::string (__func__) + ": " + err.message ());
135 }
136
137 void
138 asio_communicator::read_msg_body (boost::system::error_code const &err, size_t n)
139 {
140 if (!err)
141 on->receive (std::string (m_response.begin (), m_response.end ()));
142 else
143 throw std::runtime_error (std::string (__func__) + ": " + err.message ());
144 }