#include #include #include #include #include #include namespace fc { namespace json { class rpc_stream_connection::impl : public fc::retainable { public: fc::istream& in; fc::ostream& out; rpc_stream_connection& self; std::function on_close; impl( fc::istream& i, fc::ostream& o, rpc_stream_connection& s ) :in(i),out(o),self(s){ _read_loop_complete = fc::async( [=](){ read_loop(); } ); } ~impl() { try { self.cancel_pending_requests(); _read_loop_complete.cancel(); _read_loop_complete.wait(); } catch ( ... ) {} } fc::future _read_loop_complete; void read_loop() { try { fc::string line; fc::getline( in, line ); while( !in.eof() ) { // std::cerr<<"\n**line size: "<out.close(); my.reset(nullptr); } /** * When the connection is closed, call the given method */ void rpc_stream_connection::on_close( const std::function& oc ) { my->on_close = oc; } void rpc_stream_connection::send_invoke( uint64_t id, const fc::string& m, value&& param ) { fc::stringstream ss; ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); my->out.flush(); } void rpc_stream_connection::send_notice( const fc::string& m, value&& param ) { fc::stringstream ss; ss<<"{\"method\":\""<out.write( o.c_str(), o.size() ); my->out.flush(); } void rpc_stream_connection::send_error( uint64_t id, const json::error_object& eo ) { fc::stringstream ss; ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); my->out.flush(); } void rpc_stream_connection::send_result( uint64_t id, value&& r ) { fc::stringstream ss; ss<<"{\"id\":"<out.write( o.c_str(), o.size() ); my->out.flush(); } } } // fc::json