FC Updates from BitShares and myself #21
3 changed files with 65 additions and 9 deletions
|
|
@ -50,8 +50,13 @@ namespace fc { namespace http {
|
|||
void on_connection( const on_connection_handler& handler);
|
||||
void listen( uint16_t port );
|
||||
void listen( const fc::ip::endpoint& ep );
|
||||
uint16_t get_listening_port();
|
||||
void start_accept();
|
||||
|
||||
void stop_listening();
|
||||
void close();
|
||||
void synchronous_close();
|
||||
|
||||
private:
|
||||
friend class detail::websocket_server_impl;
|
||||
std::unique_ptr<detail::websocket_server_impl> my;
|
||||
|
|
@ -83,6 +88,9 @@ namespace fc { namespace http {
|
|||
|
||||
websocket_connection_ptr connect( const std::string& uri );
|
||||
websocket_connection_ptr secure_connect( const std::string& uri );
|
||||
|
||||
void close();
|
||||
void synchronous_close();
|
||||
private:
|
||||
std::unique_ptr<detail::websocket_client_impl> my;
|
||||
std::unique_ptr<detail::websocket_tls_client_impl> smy;
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ namespace fc { namespace http {
|
|||
|
||||
typedef websocket_client_type::connection_ptr websocket_client_connection_type;
|
||||
typedef websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type;
|
||||
using websocketpp::connection_hdl;
|
||||
|
||||
class websocket_client_impl
|
||||
{
|
||||
|
|
@ -484,6 +485,7 @@ namespace fc { namespace http {
|
|||
websocket_client_type _client;
|
||||
websocket_connection_ptr _connection;
|
||||
std::string _uri;
|
||||
fc::optional<connection_hdl> _hdl;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -625,11 +627,35 @@ namespace fc { namespace http {
|
|||
}
|
||||
void websocket_server::listen( const fc::ip::endpoint& ep )
|
||||
{
|
||||
my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
|
||||
my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
|
||||
}
|
||||
|
||||
uint16_t websocket_server::get_listening_port()
|
||||
{
|
||||
websocketpp::lib::asio::error_code ec;
|
||||
return my->_server.get_local_endpoint(ec).port();
|
||||
}
|
||||
|
||||
void websocket_server::start_accept() {
|
||||
my->_server.start_accept();
|
||||
my->_server.start_accept();
|
||||
}
|
||||
|
||||
void websocket_server::stop_listening()
|
||||
{
|
||||
my->_server.stop_listening();
|
||||
}
|
||||
|
||||
void websocket_server::close()
|
||||
{
|
||||
for (auto& connection : my->_connections)
|
||||
my->_server.close(connection.first, websocketpp::close::status::normal, "Goodbye");
|
||||
}
|
||||
|
||||
void websocket_server::synchronous_close()
|
||||
{
|
||||
close();
|
||||
while (!my->_connections.empty())
|
||||
fc::yield();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -678,6 +704,7 @@ namespace fc { namespace http {
|
|||
my->_connected = fc::promise<void>::ptr( new fc::promise<void>("websocket::connect") );
|
||||
|
||||
my->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){
|
||||
my->_hdl = hdl;
|
||||
auto con = my->_client.get_con_from_hdl(hdl);
|
||||
my->_connection = std::make_shared<detail::websocket_connection_impl<detail::websocket_client_connection_type>>( con );
|
||||
my->_closed = fc::promise<void>::ptr( new fc::promise<void>("websocket::closed") );
|
||||
|
|
@ -717,7 +744,20 @@ namespace fc { namespace http {
|
|||
smy->_client.connect(con);
|
||||
smy->_connected->wait();
|
||||
return smy->_connection;
|
||||
} FC_CAPTURE_AND_RETHROW( (uri) ) }
|
||||
} FC_CAPTURE_AND_RETHROW( (uri) ) }
|
||||
|
||||
void websocket_client::close()
|
||||
{
|
||||
if (my->_hdl)
|
||||
my->_client.close(*my->_hdl, websocketpp::close::status::normal, "Goodbye");
|
||||
}
|
||||
|
||||
void websocket_client::synchronous_close()
|
||||
{
|
||||
close();
|
||||
if (my->_closed)
|
||||
my->_closed->wait();
|
||||
}
|
||||
|
||||
websocket_connection_ptr websocket_tls_client::connect( const std::string& uri )
|
||||
{ try {
|
||||
|
|
|
|||
|
|
@ -73,12 +73,14 @@ BOOST_AUTO_TEST_CASE(login_test) {
|
|||
c->set_session_data( wsc );
|
||||
});
|
||||
|
||||
server->listen( 8090 );
|
||||
server->listen( 0 );
|
||||
auto listen_port = server->get_listening_port();
|
||||
server->start_accept();
|
||||
|
||||
try {
|
||||
auto client = std::make_shared<fc::http::websocket_client>();
|
||||
auto con = client->connect( "ws://localhost:8090" );
|
||||
auto con = client->connect( "ws://localhost:" + std::to_string(listen_port) );
|
||||
server->stop_listening();
|
||||
auto apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
|
||||
auto remote_login_api = apic->get_remote_api<login_api>();
|
||||
auto remote_calc = remote_login_api->get_calc();
|
||||
|
|
@ -87,8 +89,10 @@ BOOST_AUTO_TEST_CASE(login_test) {
|
|||
BOOST_CHECK_EQUAL(remote_calc->add( 4, 5 ), 9);
|
||||
BOOST_CHECK(remote_triggered);
|
||||
|
||||
client->synchronous_close();
|
||||
server->synchronous_close();
|
||||
fc::usleep(fc::milliseconds(50));
|
||||
client.reset();
|
||||
fc::usleep(fc::milliseconds(100));
|
||||
server.reset();
|
||||
} FC_LOG_AND_RETHROW()
|
||||
} FC_LOG_AND_RETHROW()
|
||||
|
|
@ -110,12 +114,14 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
|
|||
c->set_session_data( wsc );
|
||||
});
|
||||
|
||||
server->listen( 8090 );
|
||||
server->listen( 0 );
|
||||
auto listen_port = server->get_listening_port();
|
||||
server->start_accept();
|
||||
|
||||
try {
|
||||
auto client = std::make_shared<fc::http::websocket_client>();
|
||||
auto con = client->connect( "ws://localhost:8090" );
|
||||
auto con = client->connect( "ws://localhost:" + std::to_string(listen_port) );
|
||||
server->stop_listening();
|
||||
auto apic = std::make_shared<websocket_api_connection>(*con, MAX_DEPTH);
|
||||
auto remote_optionals = apic->get_remote_api<optionals_api>();
|
||||
|
||||
|
|
@ -124,8 +130,10 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
|
|||
BOOST_CHECK_EQUAL(remote_optionals->foo("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
|
||||
BOOST_CHECK_EQUAL(remote_optionals->foo("a", {}, "c"), "[\"a\",null,\"c\"]");
|
||||
|
||||
client->synchronous_close();
|
||||
server->synchronous_close();
|
||||
fc::usleep(fc::milliseconds(50));
|
||||
client.reset();
|
||||
fc::usleep(fc::milliseconds(100));
|
||||
server.reset();
|
||||
} FC_LOG_AND_RETHROW()
|
||||
} FC_LOG_AND_RETHROW()
|
||||
|
|
|
|||
Loading…
Reference in a new issue