@@ -34,13 +34,73 @@ class BCN_API channel_ws
3434public:
3535 typedef std::shared_ptr<node::channel_ws> ptr;
3636
37- channel_ws (const network::logger& log, const network::socket::ptr& socket,
38- uint64_t identifier, const node::configuration& config,
39- const options_t & options) NOEXCEPT
37+ // / Subscribe to messages post-upgrade (requires strand).
38+ // / Event handler is always invoked on the channel strand.
39+ template <class Message >
40+ inline void subscribe (auto && ) NOEXCEPT
41+ {
42+ BC_ASSERT (stranded ());
43+ // //using message_handler = distributor_ws::handler<Message>;
44+ // //ws_distributor_.subscribe(std::forward<message_handler>(handler));
45+ }
46+
47+ // / Serialize and write websocket message to peer (requires strand).
48+ // / Completion handler is always invoked on the channel strand.
49+ inline void send (system::data_chunk&& message, bool binary,
50+ network::result_handler&& handler) NOEXCEPT
51+ {
52+ BC_ASSERT (stranded ());
53+ BC_ASSERT (upgraded_);
54+ using namespace std ::placeholders;
55+
56+ // TODO: Serialize message.
57+ const auto ptr = system::move_shared (std::move (message));
58+ network::count_handler complete = std::bind (&channel_ws::handle_send,
59+ shared_from_base<channel_ws>(), _1, _2, ptr,
60+ std::move (handler));
61+
62+ if (!ptr)
63+ {
64+ complete (network::error::bad_alloc, {});
65+ return ;
66+ }
67+
68+ // TODO: serialize message to send.
69+ // TODO: websocket is full duplex, so writes must be queued.
70+ ws_write (network::asio::const_buffer{ ptr->data (), ptr->size () },
71+ binary, std::move (complete));
72+ }
73+
74+ inline channel_ws (const network::logger& log,
75+ const network::socket::ptr& socket, uint64_t identifier,
76+ const node::configuration& config, const options_t & options) NOEXCEPT
4077 : node::channel(log, socket, identifier, config),
4178 network::channel_ws(log, socket, identifier, config.network, options)
4279 {
4380 }
81+
82+ protected:
83+ // / Dispatch websocket buffer via derived handlers (override to handle).
84+ // / Override to handle dispatch, must invoke read_request() on complete.
85+ inline void dispatch_websocket (const network::http::flat_buffer&,
86+ size_t ) NOEXCEPT override
87+ {
88+ const std::string welcome{ " Websocket libbitcoin/4.0" };
89+ send (system::to_chunk (welcome), false , [this ](const code& ec) NOEXCEPT
90+ {
91+ // handle_send alread stops channel on ec.
92+ // One and only one handler of message must restart read loop.
93+ // In half duplex this happens only after send (ws full duplex).
94+ if (!ec) read_request ();
95+ });
96+ }
97+
98+ inline void handle_send (const code& ec, size_t , const system::chunk_ptr&,
99+ const network::result_handler& handler) NOEXCEPT
100+ {
101+ if (ec) stop (ec);
102+ handler (ec);
103+ }
44104};
45105
46106} // namespace node
0 commit comments