/* * Copyright (c) 2017-2023 zhllxt * * author : zhllxt * email : 37792738@qq.com * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef __ASIO2_RPC_SESSION_HPP__ #define __ASIO2_RPC_SESSION_HPP__ #if defined(_MSC_VER) && (_MSC_VER >= 1200) #pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #if __has_include() #include #include #include #include #include #include #include #include #include #include #include #include namespace asio2::detail { ASIO2_CLASS_FORWARD_DECLARE_BASE; ASIO2_CLASS_FORWARD_DECLARE_UDP_BASE; ASIO2_CLASS_FORWARD_DECLARE_UDP_SERVER; ASIO2_CLASS_FORWARD_DECLARE_UDP_SESSION; ASIO2_CLASS_FORWARD_DECLARE_TCP_BASE; ASIO2_CLASS_FORWARD_DECLARE_TCP_SERVER; ASIO2_CLASS_FORWARD_DECLARE_TCP_SESSION; template class rpc_session_impl_t : public executor_t , public rpc_call_cp , public rpc_recv_op , protected id_maker { friend executor_t; ASIO2_CLASS_FRIEND_DECLARE_BASE; ASIO2_CLASS_FRIEND_DECLARE_UDP_BASE; ASIO2_CLASS_FRIEND_DECLARE_UDP_SERVER; ASIO2_CLASS_FRIEND_DECLARE_UDP_SESSION; ASIO2_CLASS_FRIEND_DECLARE_TCP_BASE; ASIO2_CLASS_FRIEND_DECLARE_TCP_SERVER; ASIO2_CLASS_FRIEND_DECLARE_TCP_SESSION; public: using super = executor_t; using self = rpc_session_impl_t; using executor_type = executor_t; using args_type = typename executor_t::args_type; static constexpr asio2::net_protocol net_protocol = args_type::net_protocol; protected: using super::send; using super::async_send; public: /** * @brief constructor */ template explicit rpc_session_impl_t( rpc_invoker_t& invoker, Args&&... args ) : super(std::forward(args)...) , rpc_call_cp(this->serializer_, this->deserializer_) , rpc_recv_op() , id_maker() , invoker_(invoker) { } /** * @brief destructor */ ~rpc_session_impl_t() { } protected: inline rpc_invoker_t& _invoker() noexcept { return (this->invoker_); } inline rpc_invoker_t const& _invoker() const noexcept { return (this->invoker_); } template inline void _ws_start(std::shared_ptr& this_ptr, std::shared_ptr>& ecs, Socket& socket) { super::_ws_start(this_ptr, ecs, socket); this->derived().ws_stream().binary(true); } template inline void _handle_disconnect(const error_code& ec, std::shared_ptr this_ptr, DeferEvent chain) { while (!this->reqs_.empty()) { auto& fn = this->reqs_.begin()->second; fn(rpc::make_error_code(rpc::error::operation_aborted), std::string_view{}); } super::_handle_disconnect(ec, std::move(this_ptr), std::move(chain)); } template inline void _fire_recv( std::shared_ptr& this_ptr, std::shared_ptr>& ecs, std::string_view data) { data = detail::call_data_filter_before_recv(this->derived(), data); this->listener_.notify(event_type::recv, this_ptr, data); this->derived()._rpc_handle_recv(this_ptr, ecs, data); } protected: rpc_serializer serializer_; rpc_deserializer deserializer_; rpc_header header_; rpc_invoker_t & invoker_; }; } namespace asio2 { namespace detail { template struct template_args_rpc_session; template<> struct template_args_rpc_session : public template_args_udp_session { static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::udp; static constexpr bool rdc_call_cp_enabled = false; static constexpr std::size_t function_storage_size = 72; }; template<> struct template_args_rpc_session : public template_args_tcp_session { static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::tcp; static constexpr bool rdc_call_cp_enabled = false; static constexpr std::size_t function_storage_size = 72; }; template<> struct template_args_rpc_session : public template_args_ws_session { static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::ws; static constexpr bool rdc_call_cp_enabled = false; static constexpr std::size_t function_storage_size = 72; }; } using rpc_session_args_udp = detail::template_args_rpc_session; using rpc_session_args_tcp = detail::template_args_rpc_session; using rpc_session_args_ws = detail::template_args_rpc_session; template using rpc_session_impl_t = detail::rpc_session_impl_t; template class rpc_session_t; template class rpc_session_t : public detail::rpc_session_impl_t>> { public: using detail::rpc_session_impl_t>>::rpc_session_impl_t; }; template class rpc_session_t : public detail::rpc_session_impl_t>> { public: using detail::rpc_session_impl_t>>::rpc_session_impl_t; }; template class rpc_session_t : public detail::rpc_session_impl_t>> { public: using detail::rpc_session_impl_t>>::rpc_session_impl_t; }; template class rpc_session_use : public rpc_session_t, np> { public: using rpc_session_t, np>::rpc_session_t; }; using rpc_tcp_session = rpc_session_use; using rpc_ws_session = rpc_session_use; using rpc_kcp_session = rpc_session_use; #if !defined(ASIO2_USE_WEBSOCKET_RPC) /// Using tcp dgram mode as the underlying communication support using rpc_session = rpc_session_use; #else /// Using websocket as the underlying communication support using rpc_session = rpc_session_use; #endif } #if defined(ASIO2_INCLUDE_RATE_LIMIT) #include namespace asio2 { struct rpc_rate_session_args_tcp : public rpc_session_args_tcp { using socket_t = asio2::tcp_stream; }; struct rpc_rate_session_args_ws : public rpc_session_args_ws { using socket_t = asio2::tcp_stream; using stream_t = websocket::stream; }; template class rpc_rate_session_t; template class rpc_rate_session_t : public detail::rpc_session_impl_t> { public: using detail::rpc_session_impl_t>::rpc_session_impl_t; }; template class rpc_rate_session_t : public detail::rpc_session_impl_t> { public: using detail::rpc_session_impl_t>::rpc_session_impl_t; }; template class rpc_rate_session_use : public rpc_rate_session_t, np> { public: using rpc_rate_session_t, np>::rpc_rate_session_t; }; #if !defined(ASIO2_USE_WEBSOCKET_RPC) /// Using tcp dgram mode as the underlying communication support using rpc_rate_session = rpc_rate_session_use; #else /// Using websocket as the underlying communication support using rpc_rate_session = rpc_rate_session_use; #endif } #endif #include #endif #endif // !__ASIO2_RPC_SESSION_HPP__