more client work

This commit is contained in:
Peter Thorson
2011-12-06 08:45:59 -06:00
parent 695b8a4d30
commit f1a724e0d4
4 changed files with 192 additions and 39 deletions

View File

@@ -38,18 +38,6 @@ public:
typedef echo_server_handler type;
typedef plain_endpoint_type::connection_ptr connection_ptr;
void validate(connection_ptr connection) {
//std::cout << "state: " << connection->get_state() << std::endl;
}
void on_open(connection_ptr connection) {
//std::cout << "connection opened" << std::endl;
}
void on_close(connection_ptr connection) {
//std::cout << "connection closed" << std::endl;
}
void on_message(connection_ptr connection,websocketpp::message::data_ptr msg) {
//std::cout << "got message: " << *msg << std::endl;
connection->send(msg->get_payload(),(msg->get_opcode() == websocketpp::frame::opcode::BINARY));

View File

@@ -29,6 +29,7 @@
#define WEBSOCKETPP_ROLE_CLIENT_HPP
#include "../endpoint.hpp"
#include "../uri.hpp"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
@@ -36,6 +37,8 @@
#include <iostream>
using boost::asio::ip::tcp;
namespace websocketpp {
namespace role {
@@ -48,48 +51,159 @@ public:
public:
typedef connection<connection_type> type;
typedef endpoint endpoint_type;
connection(endpoint& e) : m_endpoint(e) {}
protected:
connection(endpoint& e) : m_endpoint(e) {}
void async_init() {
write_request();
}
void write_request() {
// async write to handle_write
}
void handle_write_request(const boost::system::error_code& error) {
if (error) {
m_endpoint.elog().at(log::elevel::ERROR) << "Error writing WebSocket request. code: " << error << log::endl;
m_connection.terminate(false);
return;
}
read_request();
}
void read_request() {
boost::asio::async_read_until(
m_connection.get_socket(),
m_connection.buffer(),
"\r\n\r\n",
boost::bind(
&type::handle_read_request,
m_connection.shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
//
void handle_read_request(const boost::system::error_code& error,
std::size_t bytes_transferred)
{
if (error) {
m_endpoint.elog().at(log::elevel::ERROR) << "Error reading HTTP request. code: " << error << log::endl;
m_connection.terminate(false);
return;
}
// read
// start session loop
}
private:
endpoint& m_endpoint;
connection_type& m_connection;
};
// handler interface callback class
class handler {
virtual void on_action() = 0;
};
typedef boost::shared_ptr<handler> handler_ptr;
// types
typedef client<endpoint> type;
typedef endpoint endpoint_type;
typedef typename endpoint_traits<endpoint>::connection_ptr connection_ptr;
typedef typename endpoint_traits<endpoint>::handler_ptr handler_ptr;
client (boost::asio::io_service& m,handler_ptr h)
: m_endpoint(static_cast< endpoint_type& >(*this)),
m_handler(h),
m_io_service(m) {}
// handler interface callback class
class handler_interface {
public:
// Required
virtual void on_open(connection_ptr connection) {};
virtual void on_close(connection_ptr connection) {};
virtual void on_fail(connection_ptr connection) {}
virtual void on_message(connection_ptr connection,message::data_ptr) {};
// Optional
virtual bool on_ping(connection_ptr connection,std::string) {return true;}
virtual void on_pong(connection_ptr connection,std::string) {}
};
void connect() {
static_cast< endpoint_type* >(this)->start();
client (boost::asio::io_service& m)
: m_state(UNINITIALIZED),
m_endpoint(static_cast< endpoint_type& >(*this)),
m_io_service(m),
m_resolver(m) {}
connection_ptr connect(const std::string& u) {
// TODO: will throw, should we catch and wrap?
uri location(u);
if (location.get_secure() && !m_endpoint.is_secure()) {
// TODO: what kind of exception does client throw?
throw "";
}
tcp::resolver::query query(location.get_host(),location.get_port_str());
tcp::resolver::iterator iterator = m_resolver.resolve(query);
connection_ptr con = m_endpoint.create_connection();
boost::asio::async_connect(
con->get_raw_socket(),
iterator,
boost::bind(
&endpoint_type::handle_connect,
endpoint_type::shared_from_this(),
con,
boost::asio::placeholders::error
)
);
m_state = CONNECTING;
return con;
}
// TODO: add a `perpetual` option
void run() {
m_io_service.run();
}
void reset() {
m_io_service.reset();
}
protected:
bool is_server() {
return false;
}
handler_ptr get_handler() {
return m_handler;
}
private:
enum state {
UNINITIALIZED = 0,
INITIALIZED = 1,
CONNECTING = 2,
CONNECTED = 3
};
void handle_connect(connection_ptr con, const boost::system::error_code& error) {
if (!error) {
m_endpoint.alog().at(log::alevel::CONNECT) << "Successful connection" << log::endl;
m_state = CONNECTED;
con->start();
} else {
m_endpoint.elog().at(log::elevel::ERROR) << "An error occurred while establishing a connection: " << error << log::endl;
// TODO: fix
throw "client error";
}
}
state m_state;
endpoint_type& m_endpoint;
handler_ptr m_handler;
boost::asio::io_service& m_io_service;
tcp::resolver m_resolver;
};

View File

@@ -389,18 +389,16 @@ public:
// handler interface callback class
class handler_interface {
public:
// Required
virtual void validate(connection_ptr connection) = 0;
virtual void on_open(connection_ptr connection) = 0;
virtual void on_close(connection_ptr connection) = 0;
virtual void validate(connection_ptr connection) {};
virtual void on_open(connection_ptr connection) {};
virtual void on_close(connection_ptr connection) {};
virtual void on_fail(connection_ptr connection) {}
virtual void on_message(connection_ptr connection,message::data_ptr) = 0;
virtual void on_message(connection_ptr connection,message::data_ptr) {};
// Optional
virtual bool on_ping(connection_ptr connection,std::string) {return true;}
virtual void on_pong(connection_ptr connection,std::string) {}
virtual void http(connection_ptr connection) {}
virtual void on_fail(connection_ptr connection) {}
};
server(boost::asio::io_service& m)

View File

@@ -171,6 +171,24 @@
B663885F1487FE6C00DDAE13 /* data.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = data.hpp; path = src/messages/data.hpp; sourceTree = "<group>"; };
B66388601487FE6C00DDAE13 /* control.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = control.hpp; path = src/messages/control.hpp; sourceTree = "<group>"; };
B6727428148517180029CF3E /* uri.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = uri.cpp; path = src/uri.cpp; sourceTree = "<group>"; };
B6732435148E543000FC2B04 /* connection_handler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = connection_handler.hpp; sourceTree = "<group>"; };
B6732436148E543000FC2B04 /* frame_parser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = frame_parser.hpp; sourceTree = "<group>"; };
B6732437148E543000FC2B04 /* session.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = session.hpp; sourceTree = "<group>"; };
B6732438148E543000FC2B04 /* policy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = policy.cpp; sourceTree = "<group>"; };
B6732439148E543000FC2B04 /* session_handler_interface.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = session_handler_interface.hpp; sourceTree = "<group>"; };
B673243A148E543000FC2B04 /* websocket_client.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_client.cpp; sourceTree = "<group>"; };
B673243B148E543000FC2B04 /* websocket_client.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_client.hpp; sourceTree = "<group>"; };
B673243C148E543000FC2B04 /* websocket_client_session.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_client_session.cpp; sourceTree = "<group>"; };
B673243D148E543000FC2B04 /* websocket_client_session.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_client_session.hpp; sourceTree = "<group>"; };
B673243E148E543000FC2B04 /* websocket_connection_handler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_connection_handler.hpp; sourceTree = "<group>"; };
B673243F148E543000FC2B04 /* websocket_endpoint.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_endpoint.hpp; sourceTree = "<group>"; };
B6732440148E543000FC2B04 /* websocket_frame.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_frame.cpp; sourceTree = "<group>"; };
B6732441148E543000FC2B04 /* websocket_server.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_server.cpp; sourceTree = "<group>"; };
B6732442148E543000FC2B04 /* websocket_server.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_server.hpp; sourceTree = "<group>"; };
B6732443148E543000FC2B04 /* websocket_server_session.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_server_session.cpp; sourceTree = "<group>"; };
B6732444148E543000FC2B04 /* websocket_server_session.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_server_session.hpp; sourceTree = "<group>"; };
B6732445148E543000FC2B04 /* websocket_session.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = websocket_session.cpp; sourceTree = "<group>"; };
B6732446148E543000FC2B04 /* websocket_session.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = websocket_session.hpp; sourceTree = "<group>"; };
B6828875143745DA002BA48B /* chat_client_handler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = chat_client_handler.cpp; path = examples/chat_client/chat_client_handler.cpp; sourceTree = "<group>"; };
B6828876143745DA002BA48B /* chat_client_handler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = chat_client_handler.hpp; path = examples/chat_client/chat_client_handler.hpp; sourceTree = "<group>"; };
B6828877143745DA002BA48B /* chat_client.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = chat_client.cpp; path = examples/chat_client/chat_client.cpp; sourceTree = "<group>"; };
@@ -355,6 +373,40 @@
name = messages;
sourceTree = "<group>";
};
B6732433148E543000FC2B04 /* legacy */ = {
isa = PBXGroup;
children = (
B6732434148E543000FC2B04 /* interfaces */,
B6732438148E543000FC2B04 /* policy.cpp */,
B6732439148E543000FC2B04 /* session_handler_interface.hpp */,
B673243A148E543000FC2B04 /* websocket_client.cpp */,
B673243B148E543000FC2B04 /* websocket_client.hpp */,
B673243C148E543000FC2B04 /* websocket_client_session.cpp */,
B673243D148E543000FC2B04 /* websocket_client_session.hpp */,
B673243E148E543000FC2B04 /* websocket_connection_handler.hpp */,
B673243F148E543000FC2B04 /* websocket_endpoint.hpp */,
B6732440148E543000FC2B04 /* websocket_frame.cpp */,
B6732441148E543000FC2B04 /* websocket_server.cpp */,
B6732442148E543000FC2B04 /* websocket_server.hpp */,
B6732443148E543000FC2B04 /* websocket_server_session.cpp */,
B6732444148E543000FC2B04 /* websocket_server_session.hpp */,
B6732445148E543000FC2B04 /* websocket_session.cpp */,
B6732446148E543000FC2B04 /* websocket_session.hpp */,
);
name = legacy;
path = src/legacy;
sourceTree = "<group>";
};
B6732434148E543000FC2B04 /* interfaces */ = {
isa = PBXGroup;
children = (
B6732435148E543000FC2B04 /* connection_handler.hpp */,
B6732436148E543000FC2B04 /* frame_parser.hpp */,
B6732437148E543000FC2B04 /* session.hpp */,
);
path = interfaces;
sourceTree = "<group>";
};
B6CF18121437C370009295BE /* echo_client */ = {
isa = PBXGroup;
children = (
@@ -404,6 +456,7 @@
B6DF1C7F1434ABB70029A1B1 /* src */ = {
isa = PBXGroup;
children = (
B6732433148E543000FC2B04 /* legacy */,
B62A5A541473EBB9005F9EB0 /* roles */,
B62A5A551473EBC4005F9EB0 /* sockets */,
B61387B51462B34400ED9B19 /* logger */,