FC Updates from BitShares and myself #21

Closed
nathanielhourt wants to merge 687 commits from dapp-support into latest-fc
3 changed files with 65 additions and 9 deletions
Showing only changes of commit bb01f3e925 - Show all commits

View file

@ -50,8 +50,13 @@ namespace fc { namespace http {
void on_connection( const on_connection_handler& handler); void on_connection( const on_connection_handler& handler);
void listen( uint16_t port ); void listen( uint16_t port );
void listen( const fc::ip::endpoint& ep ); void listen( const fc::ip::endpoint& ep );
uint16_t get_listening_port();
void start_accept(); void start_accept();
void stop_listening();
void close();
void synchronous_close();
private: private:
friend class detail::websocket_server_impl; friend class detail::websocket_server_impl;
std::unique_ptr<detail::websocket_server_impl> my; 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 connect( const std::string& uri );
websocket_connection_ptr secure_connect( const std::string& uri ); websocket_connection_ptr secure_connect( const std::string& uri );
void close();
void synchronous_close();
private: private:
std::unique_ptr<detail::websocket_client_impl> my; std::unique_ptr<detail::websocket_client_impl> my;
std::unique_ptr<detail::websocket_tls_client_impl> smy; std::unique_ptr<detail::websocket_tls_client_impl> smy;

View file

@ -431,6 +431,7 @@ namespace fc { namespace http {
typedef websocket_client_type::connection_ptr websocket_client_connection_type; typedef websocket_client_type::connection_ptr websocket_client_connection_type;
typedef websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type; typedef websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type;
using websocketpp::connection_hdl;
class websocket_client_impl class websocket_client_impl
{ {
@ -484,6 +485,7 @@ namespace fc { namespace http {
websocket_client_type _client; websocket_client_type _client;
websocket_connection_ptr _connection; websocket_connection_ptr _connection;
std::string _uri; 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 ) 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() { 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->_connected = fc::promise<void>::ptr( new fc::promise<void>("websocket::connect") );
my->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){ my->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){
my->_hdl = hdl;
auto con = my->_client.get_con_from_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->_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") ); 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->_client.connect(con);
smy->_connected->wait(); smy->_connected->wait();
return smy->_connection; 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 ) websocket_connection_ptr websocket_tls_client::connect( const std::string& uri )
{ try { { try {

View file

@ -73,12 +73,14 @@ BOOST_AUTO_TEST_CASE(login_test) {
c->set_session_data( wsc ); c->set_session_data( wsc );
}); });
server->listen( 8090 ); server->listen( 0 );
auto listen_port = server->get_listening_port();
server->start_accept(); server->start_accept();
try { try {
auto client = std::make_shared<fc::http::websocket_client>(); 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 apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
auto remote_login_api = apic->get_remote_api<login_api>(); auto remote_login_api = apic->get_remote_api<login_api>();
auto remote_calc = remote_login_api->get_calc(); 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_EQUAL(remote_calc->add( 4, 5 ), 9);
BOOST_CHECK(remote_triggered); BOOST_CHECK(remote_triggered);
client->synchronous_close();
server->synchronous_close();
fc::usleep(fc::milliseconds(50));
client.reset(); client.reset();
fc::usleep(fc::milliseconds(100));
server.reset(); server.reset();
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()
@ -110,12 +114,14 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
c->set_session_data( wsc ); c->set_session_data( wsc );
}); });
server->listen( 8090 ); server->listen( 0 );
auto listen_port = server->get_listening_port();
server->start_accept(); server->start_accept();
try { try {
auto client = std::make_shared<fc::http::websocket_client>(); 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 apic = std::make_shared<websocket_api_connection>(*con, MAX_DEPTH);
auto remote_optionals = apic->get_remote_api<optionals_api>(); 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", "b", "c"), "[\"a\",\"b\",\"c\"]");
BOOST_CHECK_EQUAL(remote_optionals->foo("a", {}, "c"), "[\"a\",null,\"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(); client.reset();
fc::usleep(fc::milliseconds(100));
server.reset(); server.reset();
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()