PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/org/zeromq/ZMQ.java

https://github.com/kalpeshptl/jzmq
Java | 1382 lines | 494 code | 169 blank | 719 comment | 53 complexity | 0e2801b2c932d5877e0beb0a7eefce75 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014
  1. /*
  2. Copyright (c) 2007-2010 iMatix Corporation
  3. This file is part of 0MQ.
  4. 0MQ is free software; you can redistribute it and/or modify it under
  5. the terms of the Lesser GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. 0MQ is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. Lesser GNU General Public License for more details.
  12. You should have received a copy of the Lesser GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package org.zeromq;
  16. import java.util.LinkedList;
  17. /**
  18. * ZeroMQ JNI Bindings.
  19. *
  20. * @author Gonzalo Diethelm
  21. *
  22. */
  23. public class ZMQ {
  24. static {
  25. // if no embedded native library, revert to loading from java.library.path
  26. if (!EmbeddedLibraryTools.LOADED_EMBEDDED_LIBRARY)
  27. System.loadLibrary ("jzmq");
  28. }
  29. // Values for flags in Socket's send and recv functions.
  30. /**
  31. * Socket flag to indicate a nonblocking send or recv mode.
  32. */
  33. public static final int NOBLOCK = 1;
  34. public static final int DONTWAIT = 1;
  35. /**
  36. * Socket flag to indicate that more message parts are coming.
  37. */
  38. public static final int SNDMORE = 2;
  39. // Socket types, used when creating a Socket.
  40. /**
  41. * Flag to specify a exclusive pair of sockets.
  42. */
  43. public static final int PAIR = 0;
  44. /**
  45. * Flag to specify a PUB socket, receiving side must be a SUB.
  46. */
  47. public static final int PUB = 1;
  48. /**
  49. * Flag to specify the receiving part of the PUB socket.
  50. */
  51. public static final int SUB = 2;
  52. /**
  53. * Flag to specify a REQ socket, receiving side must be a REP.
  54. */
  55. public static final int REQ = 3;
  56. /**
  57. * Flag to specify the receiving part of a REQ socket.
  58. */
  59. public static final int REP = 4;
  60. /**
  61. * Flag to specify a XREQ socket, receiving side must be a XREP.
  62. */
  63. public static final int XREQ = 5;
  64. /**
  65. * Flag to specify the receiving part of a XREQ socket.
  66. */
  67. public static final int XREP = 6;
  68. /**
  69. * Flag to specify the receiving part of a PUSH socket.
  70. */
  71. public static final int PULL = 7;
  72. /**
  73. * Flag to specify a PUSH socket, receiving side must be a PULL.
  74. */
  75. public static final int PUSH = 8;
  76. /**
  77. * Flag to specify a STREAMER device.
  78. */
  79. public static final int STREAMER = 1;
  80. /**
  81. * Flag to specify a FORWARDER device.
  82. */
  83. public static final int FORWARDER = 2;
  84. /**
  85. * Flag to specify a QUEUE device.
  86. */
  87. public static final int QUEUE = 3;
  88. /**
  89. * @see ZMQ#PULL
  90. */
  91. @Deprecated
  92. public static final int UPSTREAM = PULL;
  93. /**
  94. * @see ZMQ#PUSH
  95. */
  96. @Deprecated
  97. public static final int DOWNSTREAM = PUSH;
  98. /**
  99. * @return Major version number of the ZMQ library.
  100. */
  101. public static int getMajorVersion ()
  102. {
  103. return version_major ();
  104. }
  105. /**
  106. * @return Major version number of the ZMQ library.
  107. */
  108. public static int getMinorVersion ()
  109. {
  110. return version_minor ();
  111. }
  112. /**
  113. * @return Major version number of the ZMQ library.
  114. */
  115. public static int getPatchVersion ()
  116. {
  117. return version_patch ();
  118. }
  119. /**
  120. * @return Full version number of the ZMQ library used for comparing versions.
  121. */
  122. public static int getFullVersion ()
  123. {
  124. return version_full ();
  125. }
  126. /**
  127. * @param major Version major component.
  128. * @param minor Version minor component.
  129. * @param patch Version patch component.
  130. *
  131. * @return Comparible single int version number.
  132. */
  133. public static int makeVersion ( final int major,
  134. final int minor,
  135. final int patch )
  136. {
  137. return make_version ( major, minor, patch );
  138. }
  139. /**
  140. * @return String version number in the form major.minor.patch.
  141. */
  142. public static String getVersionString ()
  143. {
  144. return String.format ( "%d.%d.%d",
  145. version_major (),
  146. version_minor (),
  147. version_patch () );
  148. }
  149. protected static native int version_full();
  150. protected static native int version_major();
  151. protected static native int version_minor();
  152. protected static native int version_patch();
  153. protected static native int make_version(int major, int minor, int patch);
  154. protected static native long ENOTSUP();
  155. protected static native long EPROTONOSUPPORT();
  156. protected static native long ENOBUFS();
  157. protected static native long ENETDOWN();
  158. protected static native long EADDRINUSE();
  159. protected static native long EADDRNOTAVAIL();
  160. protected static native long ECONNREFUSED();
  161. protected static native long EINPROGRESS();
  162. protected static native long EMTHREAD();
  163. protected static native long EFSM();
  164. protected static native long ENOCOMPATPROTO();
  165. protected static native long ETERM();
  166. /**
  167. * Inner class: Error.
  168. */
  169. public enum Error {
  170. ENOTSUP(ENOTSUP()),
  171. EPROTONOSUPPORT(EPROTONOSUPPORT()),
  172. ENOBUFS(ENOBUFS()),
  173. ENETDOWN(ENETDOWN()),
  174. EADDRINUSE(EADDRINUSE()),
  175. EADDRNOTAVAIL(EADDRNOTAVAIL()),
  176. ECONNREFUSED(ECONNREFUSED()),
  177. EINPROGRESS(EINPROGRESS()),
  178. EMTHREAD(EMTHREAD()),
  179. EFSM(EFSM()),
  180. ENOCOMPATPROTO(ENOCOMPATPROTO()),
  181. ETERM(ETERM());
  182. private final long code;
  183. Error(long code) {
  184. this.code = code;
  185. }
  186. public long getCode() {
  187. return code;
  188. }
  189. public static Error findByCode(int code) {
  190. for (Error e : Error.class.getEnumConstants()) {
  191. if (e.getCode() == code) {
  192. return e;
  193. }
  194. }
  195. throw new IllegalArgumentException("Unknown " + Error.class.getName() + " enum code:" + code);
  196. }
  197. }
  198. /**
  199. * Create a new Context.
  200. *
  201. * @param ioThreads
  202. * Number of threads to use, usually 1 is sufficient for most use cases.
  203. * @return the Context
  204. */
  205. public static Context context (int ioThreads) {
  206. return new Context (ioThreads);
  207. }
  208. /**
  209. * Inner class: Context.
  210. */
  211. public static class Context {
  212. /**
  213. * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ
  214. * Context has been disposed of.
  215. */
  216. public void term () {
  217. finalize ();
  218. }
  219. /**
  220. * Create a new Socket within this context.
  221. *
  222. * @param type
  223. * the socket type.
  224. * @return the newly created Socket.
  225. */
  226. public Socket socket (int type) {
  227. return new Socket (this, type);
  228. }
  229. /**
  230. * Create a new Poller within this context, with a default size.
  231. *
  232. * @return the newly created Poller.
  233. */
  234. public Poller poller () {
  235. return new Poller (this);
  236. }
  237. /**
  238. * Create a new Poller within this context, with a specified initial size.
  239. *
  240. * @param size
  241. * the poller initial size.
  242. * @return the newly created Poller.
  243. */
  244. public Poller poller (int size) {
  245. return new Poller (this, size);
  246. }
  247. /**
  248. * Class constructor.
  249. *
  250. * @param ioThreads
  251. * size of the threads pool to handle I/O operations.
  252. */
  253. protected Context (int ioThreads) {
  254. construct (ioThreads);
  255. }
  256. /** Initialize the JNI interface */
  257. protected native void construct (int ioThreads);
  258. /** Free all resources used by JNI interface. */
  259. @Override
  260. protected native void finalize ();
  261. /**
  262. * Get the underlying context handle. This is private because it is only accessed from JNI,
  263. * where Java access controls are ignored.
  264. *
  265. * @return the internal 0MQ context handle.
  266. */
  267. private long getContextHandle () {
  268. return this.contextHandle;
  269. }
  270. /** Opaque data used by JNI driver. */
  271. private long contextHandle;
  272. }
  273. /**
  274. * Inner class: Socket.
  275. */
  276. public static class Socket {
  277. /**
  278. * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ Socket
  279. * has been disposed of.
  280. */
  281. public void close () {
  282. finalize ();
  283. }
  284. /**
  285. * The 'ZMQ_TYPE option shall retrieve the socket type for the specified
  286. * 'socket'. The socket type is specified at socket creation time and
  287. * cannot be modified afterwards.
  288. *
  289. * @return the socket type.
  290. * @since 2.1.0
  291. */
  292. public int getType () {
  293. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  294. return -1;
  295. return (int) getLongSockopt (TYPE);
  296. }
  297. /**
  298. * @see #setLinger(long)
  299. *
  300. * @return the linger period.
  301. * @since 2.1.0
  302. */
  303. public long getLinger () {
  304. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  305. return -1;
  306. return getLongSockopt (LINGER);
  307. }
  308. /**
  309. * @see #setReconnectIVL(long)
  310. *
  311. * @return the reconnectIVL.
  312. * @since 3.0.0
  313. */
  314. public long getReconnectIVL () {
  315. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  316. return -1;
  317. return getLongSockopt (RECONNECT_IVL);
  318. }
  319. /**
  320. * @see #setBacklog(long)
  321. *
  322. * @return the backlog.
  323. * @since 3.0.0
  324. */
  325. public long getBacklog () {
  326. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  327. return -1;
  328. return getLongSockopt (BACKLOG);
  329. }
  330. /**
  331. * @see #setReconnectIVLMax(long)
  332. *
  333. * @return the reconnectIVLMax.
  334. * @since 3.0.0
  335. */
  336. public long getReconnectIVLMax () {
  337. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  338. return -1;
  339. return getLongSockopt (RECONNECT_IVL_MAX);
  340. }
  341. /**
  342. * @see #setMaxMsgSize(long)
  343. *
  344. * @return the maxMsgSize.
  345. * @since 3.0.0
  346. */
  347. public long getMaxMsgSize () {
  348. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  349. return -1;
  350. return getLongSockopt (MAXMSGSIZE);
  351. }
  352. /**
  353. * @see #setSndHWM(long)
  354. *
  355. * @return the SndHWM.
  356. * @since 3.0.0
  357. */
  358. public long getSndHWM () {
  359. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  360. return -1;
  361. return getLongSockopt (SNDHWM);
  362. }
  363. /**
  364. * @see #setRcvHWM(long)
  365. *
  366. * @return the recvHWM period.
  367. * @since 3.0.0
  368. */
  369. public long getRcvHWM () {
  370. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  371. return -1;
  372. return getLongSockopt (RCVHWM);
  373. }
  374. /**
  375. * @see #setHWM(long)
  376. *
  377. * @return the High Water Mark.
  378. */
  379. public long getHWM () {
  380. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  381. return -1;
  382. return getLongSockopt (HWM);
  383. }
  384. /**
  385. * @see #setSwap(long)
  386. *
  387. * @return the number of messages to swap at most.
  388. */
  389. public long getSwap () {
  390. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  391. return -1;
  392. return getLongSockopt (SWAP);
  393. }
  394. /**
  395. * @see #setAffinity(long)
  396. *
  397. * @return the affinity.
  398. */
  399. public long getAffinity () {
  400. return getLongSockopt (AFFINITY);
  401. }
  402. /**
  403. * @see #setIdentity(byte[])
  404. *
  405. * @return the Identitiy.
  406. */
  407. public byte [] getIdentity () {
  408. return getBytesSockopt (IDENTITY);
  409. }
  410. /**
  411. * @see #setRate(long)
  412. *
  413. * @return the Rate.
  414. */
  415. public long getRate () {
  416. return getLongSockopt (RATE);
  417. }
  418. /**
  419. * @see #setRecoveryInterval(long)
  420. *
  421. * @return the RecoveryIntervall.
  422. */
  423. public long getRecoveryInterval () {
  424. return getLongSockopt (RECOVERY_IVL);
  425. }
  426. /**
  427. * @see #setMulticastLoop(boolean)
  428. *
  429. * @return the Multicast Loop.
  430. */
  431. public boolean hasMulticastLoop () {
  432. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  433. return false;
  434. return getLongSockopt (MCAST_LOOP) != 0;
  435. }
  436. /**
  437. * Sets the time-to-live field in every multicast packet sent from this socket.
  438. * The default is 1 which means that the multicast packets don't leave the local
  439. * network.
  440. *
  441. * @param mcast_hops
  442. */
  443. public void setMulticastHops (long mcast_hops) {
  444. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  445. return;
  446. setLongSockopt (MULTICAST_HOPS, mcast_hops);
  447. }
  448. /**
  449. * @see #setMulticastHops(long)
  450. *
  451. * @return the Multicast Hops.
  452. */
  453. public long getMulticastHops () {
  454. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  455. return 1;
  456. return getLongSockopt (MULTICAST_HOPS);
  457. }
  458. /**
  459. * Sets the timeout for receive operation on the socket. If the value is 0, recv
  460. * will return immediately, with a EAGAIN error if there is no message to receive.
  461. * If the value is -1, it will block until a message is available. For all other
  462. * values, it will wait for a message for that amount of time before returning with
  463. * an EAGAIN error.
  464. *
  465. * @param timeout
  466. */
  467. public void setReceiveTimeOut (long timeout) {
  468. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  469. return;
  470. setLongSockopt (RCVTIMEO, timeout);
  471. }
  472. /**
  473. * @see #setReceiveTimeOut(long)
  474. *
  475. * @return the Receive Timeout
  476. */
  477. public long getReceiveTimeOut () {
  478. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  479. return -1;
  480. return getLongSockopt (RCVTIMEO);
  481. }
  482. /**
  483. * Sets the timeout for send operation on the socket. If the value is 0, send
  484. * will return immediately, with a EAGAIN error if the message cannot be sent.
  485. * If the value is -1, it will block until the message is sent. For all other
  486. * values, it will try to send the message for that amount of time before
  487. * returning with an EAGAIN error.
  488. *
  489. * @param timeout
  490. */
  491. public void setSendTimeOut (long timeout) {
  492. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  493. return;
  494. setLongSockopt (SNDTIMEO, timeout);
  495. }
  496. /**
  497. * @see #setSendTimeOut(long)
  498. *
  499. * @return the Send Timeout.
  500. */
  501. public long getSendTimeOut () {
  502. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  503. return -1;
  504. return getLongSockopt (SNDTIMEO);
  505. }
  506. /**
  507. * @see #setSendBufferSize(long)
  508. *
  509. * @return the kernel send buffer size.
  510. */
  511. public long getSendBufferSize () {
  512. return getLongSockopt (SNDBUF);
  513. }
  514. /**
  515. * @see #setReceiveBufferSize(long)
  516. *
  517. * @return the kernel receive buffer size.
  518. */
  519. public long getReceiveBufferSize () {
  520. return getLongSockopt (RCVBUF);
  521. }
  522. /**
  523. * The 'ZMQ_RCVMORE' option shall return a boolean value indicating if the multi-part
  524. * message currently being read from the specified 'socket' has more message parts to
  525. * follow. If there are no message parts to follow or if the message currently being read is
  526. * not a multi-part message a value of zero shall be returned. Otherwise, a value of 1 shall
  527. * be returned.
  528. *
  529. * @return true if there are more messages to receive.
  530. */
  531. public boolean hasReceiveMore () {
  532. return getLongSockopt (RCVMORE) != 0;
  533. }
  534. /**
  535. * The 'ZMQ_FD' option shall retrieve file descriptor associated with the 0MQ
  536. * socket. The descriptor can be used to integrate 0MQ socket into an existing
  537. * event loop. It should never be used for anything else than polling -- such as
  538. * reading or writing. The descriptor signals edge-triggered IN event when
  539. * something has happened within the 0MQ socket. It does not necessarily mean that
  540. * the messages can be read or written. Check ZMQ_EVENTS option to find out whether
  541. * the 0MQ socket is readable or writeable.
  542. *
  543. * @return the underlying file descriptor.
  544. * @since 2.1.0
  545. */
  546. public long getFD () {
  547. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  548. return -1;
  549. return getLongSockopt (FD);
  550. }
  551. /**
  552. * The 'ZMQ_EVENTS' option shall retrieve event flags for the specified socket.
  553. * If a message can be read from the socket ZMQ_POLLIN flag is set. If message can
  554. * be written to the socket ZMQ_POLLOUT flag is set.
  555. *
  556. * @return the mask of outstanding events.
  557. * @since 2.1.0
  558. */
  559. public long getEvents () {
  560. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  561. return -1;
  562. return getLongSockopt (EVENTS);
  563. }
  564. /**
  565. * The 'ZMQ_LINGER' option shall retrieve the period for pending outbound
  566. * messages to linger in memory after closing the socket. Value of -1 means
  567. * infinite. Pending messages will be kept until they are fully transferred to
  568. * the peer. Value of 0 means that all the pending messages are dropped immediately
  569. * when socket is closed. Positive value means number of milliseconds to keep
  570. * trying to send the pending messages before discarding them.
  571. *
  572. * @param linger
  573. * the linger period.
  574. * @since 2.1.0
  575. */
  576. public void setLinger (long linger) {
  577. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  578. return;
  579. setLongSockopt (LINGER, linger);
  580. }
  581. /**
  582. * @since 3.0.0
  583. */
  584. public void setReconnectIVL (long reconnectIVL) {
  585. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  586. return;
  587. setLongSockopt (RECONNECT_IVL, reconnectIVL);
  588. }
  589. /**
  590. * @since 3.0.0
  591. */
  592. public void setBacklog (long backlog) {
  593. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  594. return;
  595. setLongSockopt (BACKLOG, backlog);
  596. }
  597. /**
  598. * @since 3.0.0
  599. */
  600. public void setReconnectIVLMax (long reconnectIVLMax) {
  601. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  602. return;
  603. setLongSockopt (RECONNECT_IVL_MAX, reconnectIVLMax);
  604. }
  605. /**
  606. * @since 3.0.0
  607. */
  608. public void setMaxMsgSize (long maxMsgSize) {
  609. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  610. return;
  611. setLongSockopt (MAXMSGSIZE, maxMsgSize);
  612. }
  613. /**
  614. * @since 3.0.0
  615. */
  616. public void setSndHWM (long sndHWM) {
  617. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  618. return;
  619. setLongSockopt (SNDHWM, sndHWM);
  620. }
  621. /**
  622. * @since 3.0.0
  623. */
  624. public void setRcvHWM (long rcvHWM) {
  625. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  626. return;
  627. setLongSockopt (RCVHWM, rcvHWM);
  628. }
  629. /**
  630. * The 'ZMQ_HWM' option shall set the high water mark for the specified 'socket'. The high
  631. * water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue
  632. * in memory for any single peer that the specified 'socket' is communicating with.
  633. *
  634. * If this limit has been reached the socket shall enter an exceptional state and depending
  635. * on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent
  636. * messages. Refer to the individual socket descriptions in the man page of zmq_socket[3] for
  637. * details on the exact action taken for each socket type.
  638. *
  639. * @param hwm
  640. * the number of messages to queue.
  641. */
  642. public void setHWM (long hwm) {
  643. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  644. return;
  645. setLongSockopt (HWM, hwm);
  646. }
  647. /**
  648. * Get the Swap. The 'ZMQ_SWAP' option shall set the disk offload (swap) size for the
  649. * specified 'socket'. A socket which has 'ZMQ_SWAP' set to a non-zero value may exceed its
  650. * high water mark; in this case outstanding messages shall be offloaded to storage on disk
  651. * rather than held in memory.
  652. *
  653. * @param swap
  654. * The value of 'ZMQ_SWAP' defines the maximum size of the swap space in bytes.
  655. */
  656. public void setSwap (long swap) {
  657. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  658. return;
  659. setLongSockopt (SWAP, swap);
  660. }
  661. /**
  662. * Get the Affinity. The 'ZMQ_AFFINITY' option shall set the I/O thread affinity for newly
  663. * created connections on the specified 'socket'.
  664. *
  665. * Affinity determines which threads from the 0MQ I/O thread pool associated with the
  666. * socket's _context_ shall handle newly created connections. A value of zero specifies no
  667. * affinity, meaning that work shall be distributed fairly among all 0MQ I/O threads in the
  668. * thread pool. For non-zero values, the lowest bit corresponds to thread 1, second lowest
  669. * bit to thread 2 and so on. For example, a value of 3 specifies that subsequent
  670. * connections on 'socket' shall be handled exclusively by I/O threads 1 and 2.
  671. *
  672. * See also in the man page of zmq_init[3] for details on allocating the number of I/O threads for a
  673. * specific _context_.
  674. *
  675. * @param affinity
  676. * the affinity.
  677. */
  678. public void setAffinity (long affinity) {
  679. setLongSockopt (AFFINITY, affinity);
  680. }
  681. /**
  682. * The 'ZMQ_IDENTITY' option shall set the identity of the specified 'socket'. Socket
  683. * identity determines if existing 0MQ infastructure (_message queues_, _forwarding
  684. * devices_) shall be identified with a specific application and persist across multiple
  685. * runs of the application.
  686. *
  687. * If the socket has no identity, each run of an application is completely separate from
  688. * other runs. However, with identity set the socket shall re-use any existing 0MQ
  689. * infrastructure configured by the previous run(s). Thus the application may receive
  690. * messages that were sent in the meantime, _message queue_ limits shall be shared with
  691. * previous run(s) and so on.
  692. *
  693. * Identity should be at least one byte and at most 255 bytes long. Identities starting with
  694. * binary zero are reserved for use by 0MQ infrastructure.
  695. *
  696. * @param identity
  697. */
  698. public void setIdentity (byte [] identity) {
  699. setBytesSockopt (IDENTITY, identity);
  700. }
  701. /**
  702. * The 'ZMQ_SUBSCRIBE' option shall establish a new message filter on a 'ZMQ_SUB' socket.
  703. * Newly created 'ZMQ_SUB' sockets shall filter out all incoming messages, therefore you
  704. * should call this option to establish an initial message filter.
  705. *
  706. * An empty 'option_value' of length zero shall subscribe to all incoming messages. A
  707. * non-empty 'option_value' shall subscribe to all messages beginning with the specified
  708. * prefix. Mutiple filters may be attached to a single 'ZMQ_SUB' socket, in which case a
  709. * message shall be accepted if it matches at least one filter.
  710. *
  711. * @param topic
  712. */
  713. public void subscribe (byte [] topic) {
  714. setBytesSockopt (SUBSCRIBE, topic);
  715. }
  716. /**
  717. * The 'ZMQ_UNSUBSCRIBE' option shall remove an existing message filter on a 'ZMQ_SUB'
  718. * socket. The filter specified must match an existing filter previously established with
  719. * the 'ZMQ_SUBSCRIBE' option. If the socket has several instances of the same filter
  720. * attached the 'ZMQ_UNSUBSCRIBE' option shall remove only one instance, leaving the rest in
  721. * place and functional.
  722. *
  723. * @param topic
  724. */
  725. public void unsubscribe (byte [] topic) {
  726. setBytesSockopt (UNSUBSCRIBE, topic);
  727. }
  728. /**
  729. * The 'ZMQ_RATE' option shall set the maximum send or receive data rate for multicast
  730. * transports such as in the man page of zmq_pgm[7] using the specified 'socket'.
  731. *
  732. * @param rate
  733. */
  734. public void setRate (long rate) {
  735. setLongSockopt (RATE, rate);
  736. }
  737. /**
  738. * The 'ZMQ_RECOVERY_IVL' option shall set the recovery interval for multicast transports
  739. * using the specified 'socket'. The recovery interval determines the maximum time in
  740. * seconds that a receiver can be absent from a multicast group before unrecoverable data
  741. * loss will occur.
  742. *
  743. * CAUTION: Excersize care when setting large recovery intervals as the data needed for
  744. * recovery will be held in memory. For example, a 1 minute recovery interval at a data rate
  745. * of 1Gbps requires a 7GB in-memory buffer. {Purpose of this Method}
  746. *
  747. * @param recovery_ivl
  748. */
  749. public void setRecoveryInterval (long recovery_ivl) {
  750. setLongSockopt (RECOVERY_IVL, recovery_ivl);
  751. }
  752. /**
  753. * The 'ZMQ_MCAST_LOOP' option shall control whether data sent via multicast transports
  754. * using the specified 'socket' can also be received by the sending host via loopback. A
  755. * value of zero disables the loopback functionality, while the default value of 1 enables
  756. * the loopback functionality. Leaving multicast loopback enabled when it is not required
  757. * can have a negative impact on performance. Where possible, disable 'ZMQ_MCAST_LOOP' in
  758. * production environments.
  759. *
  760. * @param mcast_loop
  761. */
  762. public void setMulticastLoop (boolean mcast_loop) {
  763. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  764. return;
  765. setLongSockopt (MCAST_LOOP, mcast_loop ? 1 : 0);
  766. }
  767. /**
  768. * The 'ZMQ_SNDBUF' option shall set the underlying kernel transmit buffer size for the
  769. * 'socket' to the specified size in bytes. A value of zero means leave the OS default
  770. * unchanged. For details please refer to your operating system documentation for the
  771. * 'SO_SNDBUF' socket option.
  772. *
  773. * @param sndbuf
  774. */
  775. public void setSendBufferSize (long sndbuf) {
  776. setLongSockopt (SNDBUF, sndbuf);
  777. }
  778. /**
  779. * The 'ZMQ_RCVBUF' option shall set the underlying kernel receive buffer size for the
  780. * 'socket' to the specified size in bytes. A value of zero means leave the OS default
  781. * unchanged. For details refer to your operating system documentation for the 'SO_RCVBUF'
  782. * socket option.
  783. *
  784. * @param rcvbuf
  785. */
  786. public void setReceiveBufferSize (long rcvbuf) {
  787. setLongSockopt (RCVBUF, rcvbuf);
  788. }
  789. /**
  790. * Bind to network interface. Start listening for new connections.
  791. *
  792. * @param addr
  793. * the endpoint to bind to.
  794. */
  795. public native void bind (String addr);
  796. /**
  797. * Connect to remote application.
  798. *
  799. * @param addr
  800. * the endpoint to connect to.
  801. */
  802. public native void connect (String addr);
  803. /**
  804. * Send a message.
  805. *
  806. * @param msg
  807. * the message to send, as an array of bytes.
  808. * @param flags
  809. * the flags to apply to the send operation.
  810. * @return true if send was successful, false otherwise.
  811. */
  812. public native boolean send (byte [] msg, int flags);
  813. /**
  814. * Receive a message.
  815. *
  816. * @param flags
  817. * the flags to apply to the receive operation.
  818. * @return the message received, as an array of bytes; null on error.
  819. */
  820. public native byte [] recv (int flags);
  821. /**
  822. * Receive a message in to a specified buffer.
  823. *
  824. * @param buffer
  825. * byte[] to copy zmq message payload in to.
  826. * @param offset
  827. * offset in buffer to write data
  828. * @param len
  829. * max bytes to write to buffer.
  830. * If len is smaller than the incoming message size,
  831. * the message will be truncated.
  832. * @param flags
  833. * the flags to apply to the receive operation.
  834. * @return the number of bytes read, -1 on error
  835. */
  836. public native int recv (byte[] buffer, int offset, int len, int flags);
  837. /**
  838. * Class constructor.
  839. *
  840. * @param context
  841. * a 0MQ context previously created.
  842. * @param type
  843. * the socket type.
  844. */
  845. protected Socket (Context context, int type) {
  846. // We keep a local handle to context so that
  847. // garbage collection won't be too greedy on it.
  848. this.context = context;
  849. construct (context, type);
  850. }
  851. /** Initialize the JNI interface */
  852. protected native void construct (Context ctx, int type);
  853. /** Free all resources used by JNI interface. */
  854. @Override
  855. protected native void finalize ();
  856. /**
  857. * Get the socket option value, as a long.
  858. *
  859. * @param option
  860. * ID of the option to set.
  861. * @return The socket option value (as a long).
  862. */
  863. protected native long getLongSockopt (int option);
  864. /**
  865. * Get the socket option value, as a byte array.
  866. *
  867. * @param option
  868. * ID of the option to set.
  869. * @return The socket option value (as a byte array).
  870. */
  871. protected native byte [] getBytesSockopt (int option);
  872. /**
  873. * Set the socket option value, given as a long.
  874. *
  875. * @param option
  876. * ID of the option to set.
  877. * @param optval
  878. * value (as a long) to set the option to.
  879. */
  880. protected native void setLongSockopt (int option, long optval);
  881. /**
  882. * Set the socket option value, given as a byte array.
  883. *
  884. * @param option
  885. * ID of the option to set.
  886. * @param optval
  887. * value (as a byte array) to set the option to.
  888. */
  889. protected native void setBytesSockopt (int option, byte [] optval);
  890. /**
  891. * Get the underlying socket handle. This is private because it is only accessed from JNI,
  892. * where Java access controls are ignored.
  893. *
  894. * @return the internal 0MQ socket handle.
  895. */
  896. private long getSocketHandle () {
  897. return this.socketHandle;
  898. }
  899. /** Opaque data used by JNI driver. */
  900. private long socketHandle;
  901. private Context context = null;
  902. // private Constants use the appropriate setter instead.
  903. private static final int HWM = 1;
  904. // public static final int LWM = 2; // No longer supported
  905. private static final int SWAP = 3;
  906. private static final int AFFINITY = 4;
  907. private static final int IDENTITY = 5;
  908. private static final int SUBSCRIBE = 6;
  909. private static final int UNSUBSCRIBE = 7;
  910. private static final int RATE = 8;
  911. private static final int RECOVERY_IVL = 9;
  912. private static final int MCAST_LOOP = 10;
  913. private static final int SNDBUF = 11;
  914. private static final int RCVBUF = 12;
  915. private static final int RCVMORE = 13;
  916. private static final int FD = 14;
  917. private static final int EVENTS = 15;
  918. private static final int TYPE = 16;
  919. private static final int LINGER = 17;
  920. private static final int RECONNECT_IVL = 18;
  921. private static final int BACKLOG = 19;
  922. private static final int RECONNECT_IVL_MAX = 21;
  923. private static final int MAXMSGSIZE = 22;
  924. private static final int SNDHWM = 23;
  925. private static final int RCVHWM = 24;
  926. private static final int MULTICAST_HOPS = 25;
  927. private static final int RCVTIMEO = 27;
  928. private static final int SNDTIMEO = 28;
  929. }
  930. /**
  931. * Inner class: Poller.
  932. */
  933. public static class Poller {
  934. /**
  935. * These values can be ORed to specify what we want to poll for.
  936. */
  937. public static final int POLLIN = 1;
  938. public static final int POLLOUT = 2;
  939. public static final int POLLERR = 4;
  940. /**
  941. * Register a Socket for polling on all events.
  942. *
  943. * @param socket
  944. * the Socket we are registering.
  945. * @return the index identifying this Socket in the poll set.
  946. */
  947. public int register (Socket socket) {
  948. return register (socket, POLLIN | POLLOUT | POLLERR);
  949. }
  950. /**
  951. * Register a Socket for polling on the specified events.
  952. *
  953. * Automatically grow the internal representation if needed.
  954. *
  955. * @param socket
  956. * the Socket we are registering.
  957. * @param events
  958. * a mask composed by XORing POLLIN, POLLOUT and POLLERR.
  959. * @return the index identifying this Socket in the poll set.
  960. */
  961. public int register (Socket socket, int events) {
  962. int pos = -1;
  963. if (! this.freeSlots.isEmpty()) {
  964. // If there are free slots in our array, remove one
  965. // from the free list and use it.
  966. pos = this.freeSlots.remove();
  967. } else {
  968. if (this.next >= this.size) {
  969. // It is necessary to grow the arrays.
  970. // Compute new size for internal arrays.
  971. int nsize = this.size + SIZE_INCREMENT;
  972. // Create new internal arrays.
  973. Socket [] ns = new Socket [nsize];
  974. short [] ne = new short [nsize];
  975. short [] nr = new short [nsize];
  976. // Copy contents of current arrays into new arrays.
  977. for (int i = 0; i < this.next; ++i) {
  978. ns[i] = this.sockets[i];
  979. ne[i] = this.events[i];
  980. nr[i] = this.revents[i];
  981. }
  982. // Swap internal arrays and size to new values.
  983. this.size = nsize;
  984. this.sockets = ns;
  985. this.events = ne;
  986. this.revents = nr;
  987. }
  988. pos = this.next++;
  989. }
  990. this.sockets[pos] = socket;
  991. this.events[pos] = (short) events;
  992. this.used++;
  993. return pos;
  994. }
  995. /**
  996. * Unregister a Socket for polling on the specified events.
  997. *
  998. * @param socket
  999. * the Socket to be unregistered
  1000. */
  1001. public void unregister (Socket socket) {
  1002. for (int i = 0; i < this.next; ++i) {
  1003. if (this.sockets[i] == socket) {
  1004. this.sockets[i] = null;
  1005. this.events[i] = 0;
  1006. this.revents[i] = 0;
  1007. this.freeSlots.add(i);
  1008. --this.used;
  1009. break;
  1010. }
  1011. }
  1012. }
  1013. /**
  1014. * Get the socket associated with an index.
  1015. *
  1016. * @param index
  1017. * the desired index.
  1018. * @return the Socket associated with that index (or null).
  1019. */
  1020. public Socket getSocket (int index) {
  1021. if (index < 0 || index >= this.next)
  1022. return null;
  1023. return this.sockets [index];
  1024. }
  1025. /**
  1026. * Get the current poll timeout.
  1027. *
  1028. * @return the current poll timeout in microseconds.
  1029. * @deprecated Timeout handling has been moved to the poll() methods.
  1030. */
  1031. public long getTimeout () {
  1032. return this.timeout;
  1033. }
  1034. /**
  1035. * Set the poll timeout.
  1036. *
  1037. * @param timeout
  1038. * the desired poll timeout in microseconds.
  1039. * @deprecated Timeout handling has been moved to the poll() methods.
  1040. */
  1041. public void setTimeout (long timeout) {
  1042. if (timeout < -1)
  1043. return;
  1044. this.timeout = timeout;
  1045. }
  1046. /**
  1047. * Get the current poll set size.
  1048. *
  1049. * @return the current poll set size.
  1050. */
  1051. public int getSize () {
  1052. return this.size;
  1053. }
  1054. /**
  1055. * Get the index for the next position in the poll set size.
  1056. *
  1057. * @return the index for the next position in the poll set size.
  1058. */
  1059. public int getNext () {
  1060. return this.next;
  1061. }
  1062. /**
  1063. * Issue a poll call. If the poller's internal timeout value
  1064. * has been set, use that value as timeout; otherwise, block
  1065. * indefinitely.
  1066. *
  1067. * @return how many objects where signalled by poll ().
  1068. */
  1069. public long poll () {
  1070. long tout = -1;
  1071. if (this.timeout > -1) {
  1072. tout = this.timeout;
  1073. }
  1074. return poll(tout);
  1075. }
  1076. /**
  1077. * Issue a poll call, using the specified timeout value.
  1078. * <p>
  1079. * Since ZeroMQ 3.0, the timeout parameter is in <i>milliseconds<i>,
  1080. * but prior to this the unit was <i>microseconds</i>.
  1081. *
  1082. * @param tout
  1083. * the timeout, as per zmq_poll ();
  1084. * if -1, it will block indefinitely until an event
  1085. * happens; if 0, it will return immediately;
  1086. * otherwise, it will wait for at most that many
  1087. * milliseconds/microseconds (see above).
  1088. *
  1089. * @see http://api.zeromq.org/2-1:zmq-poll
  1090. * @see http://api.zeromq.org/3-0:zmq-poll
  1091. *
  1092. * @return how many objects where signalled by poll ()
  1093. */
  1094. public long poll (long tout) {
  1095. if (tout < -1) {
  1096. return 0;
  1097. }
  1098. if (this.size <= 0 || this.next <= 0) {
  1099. return 0;
  1100. }
  1101. for (int i = 0; i < this.next; ++i) {
  1102. this.revents [i] = 0;
  1103. }
  1104. return run_poll (this.used, this.sockets, this.events, this.revents, tout);
  1105. }
  1106. /**
  1107. * Check whether the specified element in the poll set was signalled for input.
  1108. *
  1109. * @param index
  1110. *
  1111. * @return true if the element was signalled.
  1112. */
  1113. public boolean pollin (int index) {
  1114. return poll_mask (index, POLLIN);
  1115. }
  1116. /**
  1117. * Check whether the specified element in the poll set was signalled for output.
  1118. *
  1119. * @param index
  1120. *
  1121. * @return true if the element was signalled.
  1122. */
  1123. public boolean pollout (int index) {
  1124. return poll_mask (index, POLLOUT);
  1125. }
  1126. /**
  1127. * Check whether the specified element in the poll set was signalled for error.
  1128. *
  1129. * @param index
  1130. *
  1131. * @return true if the element was signalled.
  1132. */
  1133. public boolean pollerr (int index) {
  1134. return poll_mask (index, POLLERR);
  1135. }
  1136. /**
  1137. * Class constructor.
  1138. *
  1139. * @param context
  1140. * a 0MQ context previously created.
  1141. */
  1142. protected Poller (Context context) {
  1143. this(context, SIZE_DEFAULT);
  1144. }
  1145. /**
  1146. * Class constructor.
  1147. *
  1148. * @param context
  1149. * a 0MQ context previously created.
  1150. * @param size
  1151. * the number of Sockets this poller will contain.
  1152. */
  1153. protected Poller (Context context, int size) {
  1154. this.context = context;
  1155. this.size = size;
  1156. this.next = 0;
  1157. this.sockets = new Socket [this.size];
  1158. this.events = new short [this.size];
  1159. this.revents = new short [this.size];
  1160. freeSlots = new LinkedList<Integer>();
  1161. }
  1162. /**
  1163. * Issue a poll call on the specified 0MQ sockets.
  1164. * <p>
  1165. * Since ZeroMQ 3.0, the timeout parameter is in <i>milliseconds<i>,
  1166. * but prior to this the unit was <i>microseconds</i>.
  1167. *
  1168. * @param sockets
  1169. * an array of 0MQ Socket objects to poll.
  1170. * @param events
  1171. * an array of short values specifying what to poll for.
  1172. * @param revents
  1173. * an array of short values with the results.
  1174. * @param timeout
  1175. * the maximum timeout in milliseconds/microseconds (see above).
  1176. * @return how many objects where signalled by poll ().
  1177. * @see http://api.zeromq.org/2-1:zmq-poll
  1178. * @see http://api.zeromq.org/3-0:zmq-poll
  1179. */
  1180. private native long run_poll (int count, Socket [] sockets, short [] events, short [] revents, long timeout);
  1181. /**
  1182. * Check whether a specific mask was signalled by latest poll call.
  1183. *
  1184. * @param index
  1185. * the index indicating the socket.
  1186. * @param mask
  1187. * a combination of POLLIN, POLLOUT and POLLERR.
  1188. * @return true if specific socket was signalled as specified.
  1189. */
  1190. private boolean poll_mask (int index, int mask) {
  1191. if (mask <= 0 || index < 0 || index >= this.next) {
  1192. return false;
  1193. }
  1194. return (this.revents [index] & mask) > 0;
  1195. }
  1196. private Context context = null;
  1197. private long timeout = -2; // mark as uninitialized
  1198. private int size = 0;
  1199. private int next = 0;
  1200. private int used = 0;
  1201. private Socket [] sockets = null;
  1202. private short [] events = null;
  1203. private short [] revents = null;
  1204. // When socket is removed from polling, store free slots here
  1205. private LinkedList<Integer> freeSlots = null;
  1206. private static final int SIZE_DEFAULT = 32;
  1207. private static final int SIZE_INCREMENT = 16;
  1208. }
  1209. }