@@ -34,13 +34,72 @@ 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+ using namespace std ::placeholders;
54+
55+ // TODO: Serialize message.
56+ const auto ptr = system::move_shared (std::move (message));
57+ network::count_handler complete = std::bind (&channel_ws::handle_send,
58+ shared_from_base<channel_ws>(), _1, _2, ptr,
59+ std::move (handler));
60+
61+ if (!ptr)
62+ {
63+ complete (network::error::bad_alloc, {});
64+ return ;
65+ }
66+
67+ // TODO: serialize message to send.
68+ // TODO: websocket is full duplex, so writes must be queued.
69+ ws_write (network::asio::const_buffer{ ptr->data (), ptr->size () },
70+ binary, std::move (complete));
71+ }
72+
73+ inline channel_ws (const network::logger& log,
74+ const network::socket::ptr& socket, uint64_t identifier,
75+ const node::configuration& config, const options_t & options) NOEXCEPT
4076 : node::channel(log, socket, identifier, config),
4177 network::channel_ws(log, socket, identifier, config.network, options)
4278 {
4379 }
80+
81+ protected:
82+ // / Dispatch websocket buffer via derived handlers (override to handle).
83+ // / Override to handle dispatch, must invoke read_request() on complete.
84+ inline void dispatch_websocket (const network::http::flat_buffer&,
85+ size_t ) NOEXCEPT override
86+ {
87+ const std::string welcome{ " Websocket libbitcoin/4.0" };
88+ send (system::to_chunk (welcome), false , [this ](const code& ec) NOEXCEPT
89+ {
90+ // handle_send alread stops channel on ec.
91+ // One and only one handler of message must restart read loop.
92+ // In half duplex this happens only after send (ws full duplex).
93+ if (!ec) read_request ();
94+ });
95+ }
96+
97+ inline void handle_send (const code& ec, size_t , const system::chunk_ptr&,
98+ const network::result_handler& handler) NOEXCEPT
99+ {
100+ if (ec) stop (ec);
101+ handler (ec);
102+ }
44103};
45104
46105} // namespace node
0 commit comments