rpc_session.hpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_RPC_SESSION_HPP__
  11. #define __ASIO2_RPC_SESSION_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #if __has_include(<cereal/cereal.hpp>)
  16. #include <asio2/base/detail/push_options.hpp>
  17. #include <asio2/config.hpp>
  18. #include <asio2/udp/udp_session.hpp>
  19. #include <asio2/tcp/tcp_session.hpp>
  20. #include <asio2/tcp/tcps_session.hpp>
  21. #include <asio2/http/ws_session.hpp>
  22. #include <asio2/http/wss_session.hpp>
  23. #include <asio2/rpc/detail/rpc_serialization.hpp>
  24. #include <asio2/rpc/detail/rpc_protocol.hpp>
  25. #include <asio2/rpc/detail/rpc_invoker.hpp>
  26. #include <asio2/rpc/impl/rpc_recv_op.hpp>
  27. #include <asio2/rpc/impl/rpc_call_cp.hpp>
  28. namespace asio2::detail
  29. {
  30. ASIO2_CLASS_FORWARD_DECLARE_BASE;
  31. ASIO2_CLASS_FORWARD_DECLARE_UDP_BASE;
  32. ASIO2_CLASS_FORWARD_DECLARE_UDP_SERVER;
  33. ASIO2_CLASS_FORWARD_DECLARE_UDP_SESSION;
  34. ASIO2_CLASS_FORWARD_DECLARE_TCP_BASE;
  35. ASIO2_CLASS_FORWARD_DECLARE_TCP_SERVER;
  36. ASIO2_CLASS_FORWARD_DECLARE_TCP_SESSION;
  37. template<class derived_t, class executor_t>
  38. class rpc_session_impl_t
  39. : public executor_t
  40. , public rpc_call_cp<derived_t, typename executor_t::args_type>
  41. , public rpc_recv_op<derived_t, typename executor_t::args_type>
  42. , protected id_maker<typename rpc_header::id_type>
  43. {
  44. friend executor_t;
  45. ASIO2_CLASS_FRIEND_DECLARE_BASE;
  46. ASIO2_CLASS_FRIEND_DECLARE_UDP_BASE;
  47. ASIO2_CLASS_FRIEND_DECLARE_UDP_SERVER;
  48. ASIO2_CLASS_FRIEND_DECLARE_UDP_SESSION;
  49. ASIO2_CLASS_FRIEND_DECLARE_TCP_BASE;
  50. ASIO2_CLASS_FRIEND_DECLARE_TCP_SERVER;
  51. ASIO2_CLASS_FRIEND_DECLARE_TCP_SESSION;
  52. public:
  53. using super = executor_t;
  54. using self = rpc_session_impl_t<derived_t, executor_t>;
  55. using executor_type = executor_t;
  56. using args_type = typename executor_t::args_type;
  57. static constexpr asio2::net_protocol net_protocol = args_type::net_protocol;
  58. protected:
  59. using super::send;
  60. using super::async_send;
  61. public:
  62. /**
  63. * @brief constructor
  64. */
  65. template<class ...Args>
  66. explicit rpc_session_impl_t(
  67. rpc_invoker_t<derived_t, typename executor_t::args_type>& invoker,
  68. Args&&... args
  69. )
  70. : super(std::forward<Args>(args)...)
  71. , rpc_call_cp<derived_t, typename executor_t::args_type>(this->serializer_, this->deserializer_)
  72. , rpc_recv_op<derived_t, typename executor_t::args_type>()
  73. , id_maker<typename rpc_header::id_type>()
  74. , invoker_(invoker)
  75. {
  76. }
  77. /**
  78. * @brief destructor
  79. */
  80. ~rpc_session_impl_t()
  81. {
  82. }
  83. protected:
  84. inline rpc_invoker_t<derived_t, typename executor_t::args_type>& _invoker() noexcept
  85. {
  86. return (this->invoker_);
  87. }
  88. inline rpc_invoker_t<derived_t, typename executor_t::args_type> const& _invoker() const noexcept
  89. {
  90. return (this->invoker_);
  91. }
  92. template<typename C, typename Socket>
  93. inline void _ws_start(std::shared_ptr<derived_t>& this_ptr, std::shared_ptr<ecs_t<C>>& ecs, Socket& socket)
  94. {
  95. super::_ws_start(this_ptr, ecs, socket);
  96. this->derived().ws_stream().binary(true);
  97. }
  98. template<typename DeferEvent>
  99. inline void _handle_disconnect(const error_code& ec, std::shared_ptr<derived_t> this_ptr, DeferEvent chain)
  100. {
  101. while (!this->reqs_.empty())
  102. {
  103. auto& fn = this->reqs_.begin()->second;
  104. fn(rpc::make_error_code(rpc::error::operation_aborted), std::string_view{});
  105. }
  106. super::_handle_disconnect(ec, std::move(this_ptr), std::move(chain));
  107. }
  108. template<typename C>
  109. inline void _fire_recv(
  110. std::shared_ptr<derived_t>& this_ptr, std::shared_ptr<ecs_t<C>>& ecs, std::string_view data)
  111. {
  112. data = detail::call_data_filter_before_recv(this->derived(), data);
  113. this->listener_.notify(event_type::recv, this_ptr, data);
  114. this->derived()._rpc_handle_recv(this_ptr, ecs, data);
  115. }
  116. protected:
  117. rpc_serializer serializer_;
  118. rpc_deserializer deserializer_;
  119. rpc_header header_;
  120. rpc_invoker_t<derived_t, typename executor_t::args_type> & invoker_;
  121. };
  122. }
  123. namespace asio2
  124. {
  125. namespace detail
  126. {
  127. template<asio2::net_protocol np> struct template_args_rpc_session;
  128. template<>
  129. struct template_args_rpc_session<asio2::net_protocol::udp> : public template_args_udp_session
  130. {
  131. static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::udp;
  132. static constexpr bool rdc_call_cp_enabled = false;
  133. static constexpr std::size_t function_storage_size = 72;
  134. };
  135. template<>
  136. struct template_args_rpc_session<asio2::net_protocol::tcp> : public template_args_tcp_session
  137. {
  138. static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::tcp;
  139. static constexpr bool rdc_call_cp_enabled = false;
  140. static constexpr std::size_t function_storage_size = 72;
  141. };
  142. template<>
  143. struct template_args_rpc_session<asio2::net_protocol::ws> : public template_args_ws_session
  144. {
  145. static constexpr asio2::net_protocol net_protocol = asio2::net_protocol::ws;
  146. static constexpr bool rdc_call_cp_enabled = false;
  147. static constexpr std::size_t function_storage_size = 72;
  148. };
  149. }
  150. using rpc_session_args_udp = detail::template_args_rpc_session<asio2::net_protocol::udp>;
  151. using rpc_session_args_tcp = detail::template_args_rpc_session<asio2::net_protocol::tcp>;
  152. using rpc_session_args_ws = detail::template_args_rpc_session<asio2::net_protocol::ws >;
  153. template<class derived_t, class executor_t>
  154. using rpc_session_impl_t = detail::rpc_session_impl_t<derived_t, executor_t>;
  155. template<class derived_t, asio2::net_protocol np> class rpc_session_t;
  156. template<class derived_t>
  157. class rpc_session_t<derived_t, asio2::net_protocol::udp> : public detail::rpc_session_impl_t<derived_t,
  158. detail::udp_session_impl_t<derived_t, detail::template_args_rpc_session<asio2::net_protocol::udp>>>
  159. {
  160. public:
  161. using detail::rpc_session_impl_t<derived_t, detail::udp_session_impl_t<
  162. derived_t, detail::template_args_rpc_session<asio2::net_protocol::udp>>>::rpc_session_impl_t;
  163. };
  164. template<class derived_t>
  165. class rpc_session_t<derived_t, asio2::net_protocol::tcp> : public detail::rpc_session_impl_t<derived_t,
  166. detail::tcp_session_impl_t<derived_t, detail::template_args_rpc_session<asio2::net_protocol::tcp>>>
  167. {
  168. public:
  169. using detail::rpc_session_impl_t<derived_t, detail::tcp_session_impl_t<
  170. derived_t, detail::template_args_rpc_session<asio2::net_protocol::tcp>>>::rpc_session_impl_t;
  171. };
  172. template<class derived_t>
  173. class rpc_session_t<derived_t, asio2::net_protocol::ws> : public detail::rpc_session_impl_t<derived_t,
  174. detail::ws_session_impl_t<derived_t, detail::template_args_rpc_session<asio2::net_protocol::ws>>>
  175. {
  176. public:
  177. using detail::rpc_session_impl_t<derived_t, detail::ws_session_impl_t<
  178. derived_t, detail::template_args_rpc_session<asio2::net_protocol::ws>>>::rpc_session_impl_t;
  179. };
  180. template<asio2::net_protocol np>
  181. class rpc_session_use : public rpc_session_t<rpc_session_use<np>, np>
  182. {
  183. public:
  184. using rpc_session_t<rpc_session_use<np>, np>::rpc_session_t;
  185. };
  186. using rpc_tcp_session = rpc_session_use<asio2::net_protocol::tcp>;
  187. using rpc_ws_session = rpc_session_use<asio2::net_protocol::ws>;
  188. using rpc_kcp_session = rpc_session_use<asio2::net_protocol::udp>;
  189. #if !defined(ASIO2_USE_WEBSOCKET_RPC)
  190. /// Using tcp dgram mode as the underlying communication support
  191. using rpc_session = rpc_session_use<asio2::net_protocol::tcp>;
  192. #else
  193. /// Using websocket as the underlying communication support
  194. using rpc_session = rpc_session_use<asio2::net_protocol::ws>;
  195. #endif
  196. }
  197. #if defined(ASIO2_INCLUDE_RATE_LIMIT)
  198. #include <asio2/tcp/tcp_stream.hpp>
  199. namespace asio2
  200. {
  201. struct rpc_rate_session_args_tcp : public rpc_session_args_tcp
  202. {
  203. using socket_t = asio2::tcp_stream<asio2::simple_rate_policy>;
  204. };
  205. struct rpc_rate_session_args_ws : public rpc_session_args_ws
  206. {
  207. using socket_t = asio2::tcp_stream<asio2::simple_rate_policy>;
  208. using stream_t = websocket::stream<socket_t&>;
  209. };
  210. template<class derived_t, asio2::net_protocol np> class rpc_rate_session_t;
  211. template<class derived_t>
  212. class rpc_rate_session_t<derived_t, asio2::net_protocol::tcp> : public detail::rpc_session_impl_t<derived_t,
  213. detail::tcp_session_impl_t<derived_t, rpc_rate_session_args_tcp>>
  214. {
  215. public:
  216. using detail::rpc_session_impl_t<derived_t,
  217. detail::tcp_session_impl_t<derived_t, rpc_rate_session_args_tcp>>::rpc_session_impl_t;
  218. };
  219. template<class derived_t>
  220. class rpc_rate_session_t<derived_t, asio2::net_protocol::ws> : public detail::rpc_session_impl_t<derived_t,
  221. detail::ws_session_impl_t<derived_t, rpc_rate_session_args_ws>>
  222. {
  223. public:
  224. using detail::rpc_session_impl_t<derived_t,
  225. detail::ws_session_impl_t<derived_t, rpc_rate_session_args_ws>>::rpc_session_impl_t;
  226. };
  227. template<asio2::net_protocol np>
  228. class rpc_rate_session_use : public rpc_rate_session_t<rpc_rate_session_use<np>, np>
  229. {
  230. public:
  231. using rpc_rate_session_t<rpc_rate_session_use<np>, np>::rpc_rate_session_t;
  232. };
  233. #if !defined(ASIO2_USE_WEBSOCKET_RPC)
  234. /// Using tcp dgram mode as the underlying communication support
  235. using rpc_rate_session = rpc_rate_session_use<asio2::net_protocol::tcp>;
  236. #else
  237. /// Using websocket as the underlying communication support
  238. using rpc_rate_session = rpc_rate_session_use<asio2::net_protocol::ws>;
  239. #endif
  240. }
  241. #endif
  242. #include <asio2/base/detail/pop_options.hpp>
  243. #endif
  244. #endif // !__ASIO2_RPC_SESSION_HPP__