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