use of zmq.Msg in project jeromq by zeromq.
the class DealerDealerTest method testIssue131.
@Test
public void testIssue131() throws IOException {
Ctx ctx = ZMQ.createContext();
assertThat(ctx, notNullValue());
SocketBase sender = ZMQ.socket(ctx, ZMQ.ZMQ_DEALER);
assertThat(sender, notNullValue());
final int port = Utils.findOpenPort();
final String addr = "tcp://localhost:" + port;
boolean rc = ZMQ.connect(sender, addr);
assertThat(rc, is(true));
byte[] sbuf = msg(255);
int sent = ZMQ.send(sender, sbuf, 0);
assertThat(sent, is(255));
byte[] quit = { 'q' };
sent = ZMQ.send(sender, quit, 0);
assertThat(sent, is(1));
ZMQ.close(sender);
SocketBase receiver = ZMQ.socket(ctx, ZMQ.ZMQ_DEALER);
assertThat(receiver, notNullValue());
rc = ZMQ.bind(receiver, addr);
assertThat(rc, is(true));
int nbytes = 0;
do {
Msg msg = ZMQ.recv(receiver, 0);
nbytes = msg.size();
System.out.println(msg);
} while (nbytes != 1);
ZMQ.close(receiver);
ZMQ.term(ctx);
}
use of zmq.Msg in project jeromq by zeromq.
the class RouterHandoverTest method testRouterHandover.
@Test
public void testRouterHandover() throws Exception {
int rc;
boolean brc;
Ctx ctx = ZMQ.init(1);
assertThat(ctx, notNullValue());
SocketBase router = ZMQ.socket(ctx, ZMQ.ZMQ_ROUTER);
brc = ZMQ.bind(router, "tcp://127.0.0.1:*");
assertThat(brc, is(true));
// Enable the handover flag
ZMQ.setSocketOption(router, ZMQ.ZMQ_ROUTER_HANDOVER, 1);
assertThat(router, notNullValue());
// Create dealer called "X" and connect it to our router
SocketBase dealerOne = ZMQ.socket(ctx, ZMQ.ZMQ_DEALER);
assertThat(dealerOne, notNullValue());
ZMQ.setSocketOption(dealerOne, ZMQ.ZMQ_IDENTITY, "X");
String host = (String) ZMQ.getSocketOptionExt(router, ZMQ.ZMQ_LAST_ENDPOINT);
assertThat(host, notNullValue());
brc = ZMQ.connect(dealerOne, host);
assertThat(brc, is(true));
// Get message from dealer to know when connection is ready
rc = ZMQ.send(dealerOne, "Hello", 0);
assertThat(rc, is(5));
Msg msg = ZMQ.recv(router, 0);
assertThat(msg.size(), is(1));
assertThat(new String(msg.data()), is("X"));
msg = ZMQ.recv(router, 0);
assertThat(msg.size(), is(5));
// Now create a second dealer that uses the same identity
SocketBase dealerTwo = ZMQ.socket(ctx, ZMQ.ZMQ_DEALER);
assertThat(dealerTwo, notNullValue());
ZMQ.setSocketOption(dealerTwo, ZMQ.ZMQ_IDENTITY, "X");
brc = ZMQ.connect(dealerTwo, host);
assertThat(brc, is(true));
// Get message from dealer to know when connection is ready
rc = ZMQ.send(dealerTwo, "Hello", 0);
assertThat(rc, is(5));
msg = ZMQ.recv(router, 0);
assertThat(msg.size(), is(1));
assertThat(new String(msg.data()), is("X"));
msg = ZMQ.recv(router, 0);
assertThat(msg.size(), is(5));
// Send a message to 'X' identity. This should be delivered
// to the second dealer, instead of the first because of the handover.
rc = ZMQ.send(router, "X", ZMQ.ZMQ_SNDMORE);
assertThat(rc, is(1));
rc = ZMQ.send(router, "Hello", 0);
assertThat(rc, is(5));
// Ensure that the first dealer doesn't receive the message
// but the second one does
msg = ZMQ.recv(dealerOne, ZMQ.ZMQ_DONTWAIT);
assertThat(msg, nullValue());
msg = ZMQ.recv(dealerTwo, 0);
assertThat(msg.size(), is(5));
// Clean up.
ZMQ.close(router);
ZMQ.close(dealerOne);
ZMQ.close(dealerTwo);
ZMQ.term(ctx);
}
use of zmq.Msg in project jeromq by zeromq.
the class StreamEmptyTest method testStreamEmpty.
@Test
public void testStreamEmpty() throws IOException, InterruptedException {
String host = "tcp://localhost:*";
Ctx ctx = ZMQ.init(1);
assert (ctx != null);
// Set up listener STREAM.
SocketBase bind = ZMQ.socket(ctx, ZMQ.ZMQ_STREAM);
assert (bind != null);
boolean rc = ZMQ.bind(bind, host);
assert (rc);
host = (String) ZMQ.getSocketOptionExt(bind, ZMQ.ZMQ_LAST_ENDPOINT);
assertThat(host, notNullValue());
// Set up connection stream.
SocketBase connect = ZMQ.socket(ctx, ZMQ.ZMQ_DEALER);
assert (connect != null);
// Do the connection.
rc = ZMQ.connect(connect, host);
assert (rc);
ZMQ.sleep(1);
int ret = ZMQ.send(connect, "", 0);
assertThat(ret, is(0));
Msg msg = ZMQ.recv(bind, 0);
assertThat(msg, notNullValue());
assertThat(msg.size(), is(5));
ret = ZMQ.send(bind, msg, ZMQ.ZMQ_SNDMORE);
assertThat(ret, is(5));
ret = ZMQ.send(bind, new Msg(), 0);
assertThat(ret, is(0));
ZMQ.setSocketOption(bind, ZMQ.ZMQ_LINGER, 0);
ZMQ.setSocketOption(connect, ZMQ.ZMQ_LINGER, 0);
ZMQ.close(bind);
ZMQ.close(connect);
ZMQ.term(ctx);
}
use of zmq.Msg in project jeromq by zeromq.
the class StreamEngine method outEvent.
@Override
public void outEvent() {
assert (!ioError);
// If write buffer is empty, try to read new data from the encoder.
if (outsize == 0) {
// more time due to 'speculative write' optimization.
if (encoder == null) {
assert (handshaking);
return;
}
outpos.set(null);
outsize = encoder.encode(outpos, 0);
// Make sure batch sizes match large buffer sizes
final int outBatchSize = Math.max(options.sndbuf, Config.OUT_BATCH_SIZE.getValue());
while (outsize < outBatchSize) {
Msg msg = nextMsg.get();
if (msg == null) {
break;
}
encoder.loadMsg(msg);
int n = encoder.encode(outpos, outBatchSize - outsize);
assert (n > 0);
outsize += n;
}
// If there is no data to send, stop polling for output.
if (outsize == 0) {
outputStopped = true;
ioObject.resetPollOut(handle);
return;
}
// slight difference with libzmq:
// encoder is notified of the end of the loading
encoder.encoded();
}
// If there are any data to write in write buffer, write as much as
// possible to the socket. Note that amount of data to write can be
// arbitrarily large. However, we assume that underlying TCP layer has
// limited transmission buffer and thus the actual number of bytes
// written should be reasonably modest.
int nbytes = write(outpos.get());
// this is necessary to prevent losing incoming messages.
if (nbytes == -1) {
ioObject.resetPollOut(handle);
return;
}
outsize -= nbytes;
// to send, stop polling for output.
if (handshaking) {
if (outsize == 0) {
ioObject.resetPollOut(handle);
}
}
}
use of zmq.Msg in project jeromq by zeromq.
the class StreamEngine method handshake.
// Detects the protocol used by the peer.
private boolean handshake() {
assert (handshaking);
assert (greetingRecv.position() < greetingSize);
final Mechanisms mechanism = options.mechanism;
assert (mechanism != null);
// Position of the version field in the greeting.
final int revisionPos = SIGNATURE_SIZE;
// Make sure batch sizes match large buffer sizes
final int inBatchSize = Math.max(options.rcvbuf, Config.IN_BATCH_SIZE.getValue());
final int outBatchSize = Math.max(options.sndbuf, Config.OUT_BATCH_SIZE.getValue());
// Receive the greeting.
while (greetingRecv.position() < greetingSize) {
final int n = read(greetingRecv);
if (n == 0) {
error(ErrorReason.CONNECTION);
return false;
}
if (n == -1) {
if (!errno.is(ZError.EAGAIN)) {
error(ErrorReason.CONNECTION);
}
return false;
}
// peer is using unversioned protocol.
if ((greetingRecv.get(0) & 0xff) != 0xff) {
// then the other peer is using ZMTP 1.0.
break;
}
if (greetingRecv.position() < SIGNATURE_SIZE) {
continue;
}
// (i.e. the peer is using the unversioned protocol).
if ((greetingRecv.get(9) & 0x01) != 0x01) {
break;
}
// If the least significant bit is 1, the peer is using ZMTP 2.0 or later
// and has sent us the ZMTP signature.
int outpos = greetingSend.position();
// Send the major version number.
if (greetingSend.limit() == SIGNATURE_SIZE) {
if (outsize == 0) {
ioObject.setPollOut(handle);
}
greetingSend.limit(SIGNATURE_SIZE + 1);
// Major version number
greetingSend.put(revisionPos, Protocol.V3.revision);
outsize += 1;
}
if (greetingRecv.position() > SIGNATURE_SIZE) {
if (greetingSend.limit() == SIGNATURE_SIZE + 1) {
if (outsize == 0) {
ioObject.setPollOut(handle);
}
// We read a further byte, which indicates the ZMTP version.
byte protocol = greetingRecv.get(revisionPos);
if (protocol == Protocol.V1.revision || protocol == Protocol.V2.revision) {
// If this is V1 or V2, we have a ZMTP 2.0 peer.
greetingSend.limit(V2_GREETING_SIZE);
greetingSend.position(SIGNATURE_SIZE + 1);
// Socket type
greetingSend.put((byte) options.type);
outsize += 1;
} else {
// If this is 3 or greater, we have a ZMTP 3.0 peer.
greetingSend.limit(V3_GREETING_SIZE);
greetingSend.position(SIGNATURE_SIZE + 1);
// Minor version number
greetingSend.put((byte) 0);
outsize += 1;
greetingSend.mark();
greetingSend.put(new byte[20]);
assert (mechanism == Mechanisms.NULL || mechanism == Mechanisms.PLAIN || mechanism == Mechanisms.CURVE || mechanism == Mechanisms.GSSAPI);
greetingSend.reset();
greetingSend.put(mechanism.name().getBytes(ZMQ.CHARSET));
greetingSend.reset();
greetingSend.position(greetingSend.position() + 20);
outsize += 20;
greetingSend.put(new byte[32]);
outsize += 32;
greetingSize = V3_GREETING_SIZE;
}
}
}
greetingSend.position(outpos);
}
// messages.
if ((greetingRecv.get(0) & 0xff) != 0xff || (greetingRecv.get(9) & 0x01) == 0) {
// If the least significant bit is 0, then the other peer is using ZMTP 1.0.
if (session.zapEnabled()) {
// reject ZMTP 1.0 connections if ZAP is enabled
error(ErrorReason.PROTOCOL);
return false;
}
zmtpVersion = Protocol.V0;
encoder = new V1Encoder(errno, outBatchSize);
decoder = new V1Decoder(errno, inBatchSize, options.maxMsgSize, options.allocator);
// We have already sent the message header.
// Since there is no way to tell the encoder to
// skip the message header, we simply throw that
// header data away.
final int headerSize = options.identitySize + 1 >= 255 ? 10 : 2;
ByteBuffer tmp = ByteBuffer.allocate(headerSize);
// Prepare the identity message and load it into encoder.
// Then consume bytes we have already sent to the peer.
Msg txMsg = new Msg(options.identitySize);
txMsg.put(options.identity, 0, options.identitySize);
encoder.loadMsg(txMsg);
ValueReference<ByteBuffer> bufferp = new ValueReference<>(tmp);
int bufferSize = encoder.encode(bufferp, headerSize);
assert (bufferSize == headerSize);
// Make sure the decoder sees the data we have already received.
decodeDataAfterHandshake(0);
// message into the incoming message stream.
if (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB) {
subscriptionRequired = true;
}
// We are sending our identity now and the next message
// will come from the socket.
nextMsg = pullMsgFromSession;
// We are expecting identity message.
processMsg = processIdentity;
} else if (greetingRecv.get(revisionPos) == Protocol.V1.revision) {
// ZMTP/1.0 framing.
zmtpVersion = Protocol.V1;
if (session.zapEnabled()) {
// reject ZMTP 1.0 connections if ZAP is enabled
error(ErrorReason.PROTOCOL);
return false;
}
encoder = new V1Encoder(errno, outBatchSize);
decoder = new V1Decoder(errno, inBatchSize, options.maxMsgSize, options.allocator);
decodeDataAfterHandshake(V2_GREETING_SIZE);
} else if (greetingRecv.get(revisionPos) == Protocol.V2.revision) {
// ZMTP/2.0 framing.
zmtpVersion = Protocol.V2;
if (session.zapEnabled()) {
// reject ZMTP 2.0 connections if ZAP is enabled
error(ErrorReason.PROTOCOL);
return false;
}
encoder = new V2Encoder(errno, outBatchSize);
decoder = new V2Decoder(errno, inBatchSize, options.maxMsgSize, options.allocator);
decodeDataAfterHandshake(V2_GREETING_SIZE);
} else {
zmtpVersion = Protocol.V3;
encoder = new V2Encoder(errno, outBatchSize);
decoder = new V2Decoder(errno, inBatchSize, options.maxMsgSize, options.allocator);
greetingRecv.position(V2_GREETING_SIZE);
if (mechanism.isMechanism(greetingRecv)) {
this.mechanism = mechanism.create(session, peerAddress, options);
} else {
error(ErrorReason.PROTOCOL);
return false;
}
nextMsg = nextHandshakeCommand;
processMsg = processHandshakeCommand;
}
// Start polling for output if necessary.
if (outsize == 0) {
ioObject.setPollOut(handle);
}
// Handshaking was successful.
// Switch into the normal message flow.
handshaking = false;
if (hasHandshakeTimer) {
ioObject.cancelTimer(HANDSHAKE_TIMER_ID);
hasHandshakeTimer = false;
}
socket.eventHandshaken(endpoint, zmtpVersion.ordinal());
return true;
}
Aggregations