PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/zmqpp/socket.hpp

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