PageRenderTime 63ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/zmqpp/zmqpp/socket.hpp

https://gitlab.com/IlluminatiCore/IlluminatiCore
C++ Header | 500 lines | 111 code | 53 blank | 336 comment | 9 complexity | f0d5fad1dd2f332d9ecee58117a8bbc2 MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause
  1. /**
  2. * \file
  3. *
  4. * \date 9 Aug 2011
  5. * \author Ben Gray (\@benjamg)
  6. */
  7. #ifndef ZMQPP_SOCKET_HPP_
  8. #define ZMQPP_SOCKET_HPP_
  9. #include <cstring>
  10. #include <string>
  11. #include <list>
  12. #include <zmq.h>
  13. #include "compatibility.hpp"
  14. #include "socket_types.hpp"
  15. #include "socket_options.hpp"
  16. namespace zmqpp
  17. {
  18. class context;
  19. class message;
  20. typedef std::string endpoint_t;
  21. typedef context context_t;
  22. typedef message message_t;
  23. /*!
  24. * The socket class represents the zmq sockets.
  25. *
  26. * A socket can be bound and/or connected to as many endpoints as required
  27. * with the sole exception of a ::pair socket.
  28. *
  29. * The routing is handled by zmq based on the type set.
  30. *
  31. * The bound side of an inproc connection must occur first and inproc can only
  32. * connect to other inproc sockets of the same context.
  33. *
  34. * This class is c++0x move supporting and cannot be copied.
  35. */
  36. class socket
  37. {
  38. public:
  39. static const int normal; /*!< /brief default send type, no flags set */
  40. #if (ZMQ_VERSION_MAJOR == 2)
  41. static const int dont_wait; /*!< /brief don't block if sending is not currently possible */
  42. #else
  43. static const int dont_wait; /*!< /brief don't block if sending is not currently possible */
  44. #endif
  45. static const int send_more; /*!< /brief more parts will follow this one */
  46. #ifdef ZMQ_EXPERIMENTAL_LABELS
  47. static const int send_label; /*!< /brief this message part is an internal zmq label */
  48. #endif
  49. /*!
  50. * Create a socket for a given type.
  51. *
  52. * \param context the zmq context under which the socket will live
  53. * \param type a valid ::socket_type for the socket
  54. */
  55. socket(context_t const& context, socket_type const type);
  56. /*!
  57. * This will close any socket still open before returning
  58. */
  59. ~socket();
  60. /*!
  61. * Get the type of the socket, this works on zmqpp types and not the zmq internal types.
  62. * Use the socket::get method if you wish to intergoate the zmq internal ones.
  63. *
  64. * \return the type of the socket
  65. */
  66. socket_type type() const { return _type; }
  67. /*!
  68. * Asynchronously binds to an endpoint.
  69. *
  70. * \param endpoint the zmq endpoint to bind to
  71. */
  72. void bind(endpoint_t const& endpoint);
  73. /*!
  74. * Unbinds from a previously bound endpoint.
  75. *
  76. * \param endpoint the zmq endpoint to bind to
  77. */
  78. void unbind(endpoint_t const& endpoint);
  79. /*!
  80. * Asynchronously connects to an endpoint.
  81. * If the endpoint is not inproc then zmq will happily keep trying
  82. * to connect until there is something there.
  83. *
  84. * Inproc sockets must have a valid target already bound before connection
  85. * will work.
  86. *
  87. * \param endpoint the zmq endpoint to connect to
  88. */
  89. void connect(endpoint_t const& endpoint);
  90. /*!
  91. * Asynchronously connects to multiple endpoints.
  92. * If the endpoint is not inproc then zmq will happily keep trying
  93. * to connect until there is something there.
  94. *
  95. * Inproc sockets must have a valid target already bound before connection
  96. * will work.
  97. *
  98. * This is a helper function that wraps the single item connect in a loop
  99. *
  100. * \param connections_begin the starting iterator for zmq endpoints.
  101. * \param connections_end the final iterator for zmq endpoints.
  102. */
  103. template<typename InputIterator>
  104. void connect(InputIterator const& connections_begin, InputIterator const& connections_end)
  105. {
  106. for(InputIterator it = connections_begin; it != connections_end; ++it)
  107. {
  108. connect(*it);
  109. }
  110. }
  111. /*!
  112. * Disconnects a previously connected endpoint.
  113. *
  114. * \param endpoint the zmq endpoint to disconnect from
  115. */
  116. void disconnect(endpoint_t const& endpoint);
  117. /*!
  118. * Disconnects from multiple previously connected endpoints.
  119. *
  120. * This is a helper function that wraps the single item disconnect in a loop
  121. *
  122. * \param disconnections_begin the starting iterator for zmq endpoints.
  123. * \param disconnections_end the final iterator for zmq endpoints.
  124. */
  125. template<typename InputIterator>
  126. void disconnect(InputIterator const& disconnections_begin, InputIterator const& disconnections_end)
  127. {
  128. for(InputIterator it = disconnections_begin; it != disconnections_end; ++it)
  129. {
  130. disconnect(*it);
  131. }
  132. }
  133. /*!
  134. * Closes the internal zmq socket and marks this instance
  135. * as invalid.
  136. */
  137. void close();
  138. /*!
  139. * Sends the message over the connection, this may be a multipart message.
  140. *
  141. * If dont_block is true and we are unable to add a new message then this
  142. * function will return false.
  143. *
  144. * \param message message to send
  145. * \param dont_block boolean to dictate if we wait while sending.
  146. * \return true if message sent, false if it would have blocked
  147. */
  148. bool send(message_t& message, bool const dont_block = false);
  149. /*!
  150. * Gets a message from the connection, this may be a multipart message.
  151. *
  152. * If dont_block is true and we are unable to get a message then this
  153. * function will return false.
  154. *
  155. * \param message reference to fill with received data
  156. * \param dont_block boolean to dictate if we wait for data.
  157. * \return true if message sent, false if it would have blocked
  158. */
  159. bool receive(message_t& message, bool const dont_block = false);
  160. /*!
  161. * Sends the byte data held by the string as the next message part.
  162. *
  163. * If the socket::DONT_WAIT flag and we are unable to add a new message to
  164. * socket then this function will return false.
  165. *
  166. * \param string message part to send
  167. * \param flags message send flags
  168. * \return true if message part sent, false if it would have blocked
  169. */
  170. bool send(std::string const& string, int const flags = normal);
  171. /*!
  172. * If there is a message ready then get the next part as a string
  173. *
  174. * If the socket::DONT_WAIT flag and there is no message ready to receive
  175. * then this function will return false.
  176. *
  177. * \param string message part to receive into
  178. * \param flags message receive flags
  179. * \return true if message part received, false if it would have blocked
  180. */
  181. bool receive(std::string& string, int const flags = normal);
  182. /*!
  183. * Sends the byte data pointed to by buffer as the next part of the message.
  184. *
  185. * If the socket::DONT_WAIT flag and we are unable to add a new message to
  186. * socket then this function will return false.
  187. *
  188. * \param buffer byte buffer pointer to start writing from
  189. * \param length max length of the buffer
  190. * \param flags message send flags
  191. * \return true if message part sent, false if it would have blocked
  192. */
  193. bool send_raw(char const* buffer, int const length, int const flags = normal);
  194. /*!
  195. * \warning If the buffer is not large enough for the message part then the
  196. * data will be truncated. The rest of the part is lost forever.
  197. *
  198. * If there is a message ready then get the next part of it as a raw
  199. * byte buffer.
  200. *
  201. * If the socket::DONT_WAIT flag and there is no message ready to receive
  202. * then this function will return false.
  203. *
  204. * \param buffer byte buffer pointer to start writing to
  205. * \param length max length of the buffer
  206. * \param flags message receive flags
  207. * \return true if message part received, false if it would have blocked
  208. */
  209. bool receive_raw(char* buffer, int& length, int const flags = normal);
  210. /*!
  211. *
  212. * Subscribe to a topic
  213. *
  214. * Helper function that is equivalent of calling
  215. * \code
  216. * set(zmqpp::socket_option::subscribe, topic);
  217. * \endcode
  218. *
  219. * This method is only useful for subscribe type sockets.
  220. *
  221. * \param topic the topic to subscribe to.
  222. */
  223. void subscribe(std::string const& topic);
  224. /*!
  225. * Subscribe to a topic
  226. *
  227. * Helper function that is equivalent of a loop calling
  228. * \code
  229. * set(zmqpp::socket_option::subscribe, topic);
  230. * \endcode
  231. *
  232. * This method is only useful for subscribe type sockets.
  233. *
  234. * Generally this will be used with stl collections using begin() and
  235. * end() functions to get the iterators.
  236. * For this reason the end loop runs until the end iterator, not inclusive
  237. * of it.
  238. *
  239. * \param topics_begin the starting iterator for topics.
  240. * \param topics_end the final iterator for topics.
  241. */
  242. template<typename InputIterator>
  243. void subscribe(InputIterator const& topics_begin, InputIterator const& topics_end)
  244. {
  245. for(InputIterator it = topics_begin; it != topics_end; ++it)
  246. {
  247. subscribe(*it);
  248. }
  249. }
  250. /*!
  251. * Unsubscribe from a topic
  252. *
  253. * Helper function that is equivalent of calling
  254. * \code
  255. * set(zmqpp::socket_option::unsubscribe, topic);
  256. * \endcode
  257. *
  258. * This method is only useful for subscribe type sockets.
  259. *
  260. * \param topic the topic to unsubscribe from.
  261. */
  262. void unsubscribe(std::string const& topic);
  263. /*!
  264. * Unsubscribe from a topic
  265. *
  266. * Helper function that is equivalent of a loop calling
  267. * \code
  268. * set(zmqpp::socket_option::unsubscribe, topic);
  269. * \endcode
  270. *
  271. * This method is only useful for subscribe type sockets.
  272. *
  273. * Generally this will be used with stl collections using begin() and
  274. * end() functions to get the iterators.
  275. * For this reason the end loop runs until the end iterator, not inclusive
  276. * of it.
  277. *
  278. * \param topics_begin the starting iterator for topics.
  279. * \param topics_end the final iterator for topics.
  280. */
  281. template<typename InputIterator>
  282. void unsubscribe(InputIterator const& topics_begin, InputIterator const& topics_end)
  283. {
  284. for(InputIterator it = topics_begin; it != topics_end; ++it)
  285. {
  286. unsubscribe(*it);
  287. }
  288. }
  289. /*!
  290. * If the last receive part call to the socket resulted
  291. * in a label or a non-terminating part of a multipart
  292. * message this will return true.
  293. *
  294. * \return true if there are more parts
  295. */
  296. bool has_more_parts() const;
  297. /*!
  298. * Set the value of an option in the underlaying zmq socket.
  299. *
  300. * \param option a valid ::socket_option
  301. * \param value to set the option to
  302. */
  303. void set(socket_option const option, int const value);
  304. /*!
  305. * Set the value of an option in the underlaying zmq socket.
  306. *
  307. * \since 2.0.0 (built against 0mq version 3.1.x or later)
  308. *
  309. * \param option a valid ::socket_option
  310. * \param value to set the option to
  311. */
  312. void set(socket_option const option, bool const value);
  313. /*!
  314. * Set the value of an option in the underlaying zmq socket.
  315. *
  316. * \param option a valid ::socket_option
  317. * \param value to set the option to
  318. */
  319. void set(socket_option const option, uint64_t const value);
  320. /*!
  321. * Set the value of an option in the underlaying zmq socket.
  322. *
  323. * \param option a valid ::socket_option
  324. * \param value to set the option to
  325. */
  326. void set(socket_option const option, int64_t const value);
  327. /*!
  328. * Set the value of an option in the underlaying zmq socket.
  329. *
  330. * \param option a valid ::socket_option
  331. * \param pointer to raw byte value to set the option to
  332. * \param length the size of the raw byte value
  333. */
  334. void set(socket_option const option, char const* value, size_t const length);
  335. /*!
  336. * Set the value of an option in the underlaying zmq socket.
  337. *
  338. * \param option a valid ::socket_option
  339. * \param pointer to null terminated cstring value to set the option to
  340. */
  341. inline void set(socket_option const option, char const* value) { set(option, value, strlen(value)); }
  342. /*!
  343. * Set the value of an option in the underlaying zmq socket.
  344. *
  345. * \param option a valid ::socket_option
  346. * \param value to set the option to
  347. */
  348. inline void set(socket_option const option, std::string const value) { set(option, value.c_str(), value.length()); }
  349. /*!
  350. * Get a socket option from the underlaying zmq socket.
  351. *
  352. * \param option a valid ::socket_option
  353. * \param value referenced int to return value in
  354. */
  355. void get(socket_option const option, int& value) const;
  356. /*!
  357. * Get a socket option from the underlaying zmq socket.
  358. *
  359. * \param option a valid ::socket_option
  360. * \param value referenced bool to return value in
  361. */
  362. void get(socket_option const option, bool& value) const;
  363. /*!
  364. * Get a socket option from the underlaying zmq socket.
  365. *
  366. * \param option a valid ::socket_option
  367. * \param value referenced uint64_t to return value in
  368. */
  369. void get(socket_option const option, uint64_t& value) const;
  370. /*!
  371. * Get a socket option from the underlaying zmq socket.
  372. *
  373. * \param option a valid ::socket_option
  374. * \param value referenced uint64_t to return value in
  375. */
  376. void get(socket_option const option, int64_t& value) const;
  377. /*!
  378. * Get a socket option from the underlaying zmq socket.
  379. *
  380. * \param option a valid ::socket_option
  381. * \param value referenced std::string to return value in
  382. */
  383. void get(socket_option const option, std::string& value) const;
  384. /*!
  385. * For those that don't want to get into a referenced value this templated method
  386. * will return the value instead.
  387. *
  388. * \param option a valid ::socket_option
  389. * \return socket option value
  390. */
  391. template<typename Type>
  392. Type get(socket_option const option) const
  393. {
  394. Type value = Type();
  395. get(option, value);
  396. return value;
  397. }
  398. /*!
  399. * Move constructor
  400. *
  401. * Moves the internals of source to this object, there is no guarantee
  402. * that source will be left in a valid state.
  403. *
  404. * This constructor is noexcept and so will not throw exceptions
  405. *
  406. * \param source target socket to steal internals from
  407. */
  408. socket(socket&& source) NOEXCEPT;
  409. /*!
  410. * Move operator
  411. *
  412. * Moves the internals of source to this object, there is no guarantee
  413. * that source will be left in a valid state.
  414. *
  415. * This function is noexcept and so will not throw exceptions
  416. *
  417. * \param source target socket to steal internals from
  418. * \return socket reference to this
  419. */
  420. socket& operator=(socket&& source) NOEXCEPT;
  421. /*!
  422. * Check the socket is still valid
  423. *
  424. * This tests the internal state of the socket.
  425. * If creation failed for some reason or if the move functions were used
  426. * to move the socket internals to another instance this will return false.
  427. *
  428. * \return true if the socket is valid
  429. */
  430. operator bool() const;
  431. /*!
  432. * Access to the raw 0mq context
  433. *
  434. * \return void pointer to the underlying 0mq socket
  435. */
  436. operator void*() const;
  437. private:
  438. void* _socket;
  439. socket_type _type;
  440. zmq_msg_t _recv_buffer;
  441. // No copy
  442. socket(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
  443. socket& operator=(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
  444. void track_message(message_t const&, uint32_t const, bool&);
  445. };
  446. }
  447. #endif /* ZMQPP_SOCKET_HPP_ */