String getClientId() { return NettyUtils.clientID(channel); }
void sendSubAckMessage(int messageID, MqttSubAckMessage ackMessage) { final String clientId = NettyUtils.clientID(channel); LOG.trace("Sending SUBACK response CId={}, messageId: {}", clientId, messageID); channel.writeAndFlush(ackMessage).addListener(FIRE_EXCEPTION_ON_FAILURE); }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { LOG.error("Unexpected exception while processing MQTT message. Closing Netty channel. CId={}", NettyUtils.clientID(ctx.channel()), cause); ctx.close().addListener(CLOSE_ON_FAILURE); }
/** * Is called when the write timeout expire. * * @param ctx the channel context. */ private void channelIdle(ChannelHandlerContext ctx) { // ctx.fireUserEventTriggered(evt); if (LOG.isTraceEnabled()) { LOG.trace("Flushing idle Netty channel {} Cid: {}", ctx.channel(), NettyUtils.clientID(ctx.channel())); } ctx.channel().flush(); }
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { String clientID = NettyUtils.clientID(ctx.channel()); if (clientID != null && !clientID.isEmpty()) { LOG.info("Channel closed <{}>", clientID); } ctx.fireChannelInactive(); }
private void resendNotAcked(ChannelHandlerContext ctx/* , IdleStateEvent evt */) { if (LOG.isTraceEnabled()) { LOG.trace("Flushing idle Netty channel {} for clientId: {}", ctx.channel(), NettyUtils.clientID(ctx.channel())); } ctx.fireUserEventTriggered(new ResendNotAckedPublishes()); } }
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { String clientID = NettyUtils.clientID(ctx.channel()); if (clientID != null && !clientID.isEmpty()) { this.connectedClientsMetrics.dec(); } ctx.fireChannelInactive(); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleState e = ((IdleStateEvent) evt).state(); if (e == IdleState.READER_IDLE) { LOG.info("Firing channel inactive event. MqttClientId = {}.", NettyUtils.clientID(ctx.channel())); // fire a close that then fire channelInactive to trigger publish of Will ctx.close().addListener(CLOSE_ON_FAILURE); } } else { if (LOG.isTraceEnabled()) { LOG.trace("Firing Netty event CId = {}, eventClass = {}", NettyUtils.clientID(ctx.channel()), evt.getClass().getName()); } super.userEventTriggered(ctx, evt); } } }
void processDisconnect(MqttMessage msg) { final String clientID = NettyUtils.clientID(channel); LOG.trace("Start DISCONNECT CId={}, channel: {}", clientID, channel); if (!connected) { LOG.info("DISCONNECT received on already closed connection, CId={}, channel: {}", clientID, channel); return; } sessionRegistry.disconnect(clientID); connected = false; channel.close().addListener(FIRE_EXCEPTION_ON_FAILURE); LOG.trace("Processed DISCONNECT CId={}, channel: {}", clientID, channel); String userName = NettyUtils.userName(channel); postOffice.dispatchDisconnection(clientID,userName); LOG.trace("dispatch disconnection: clientId={}, userName={}", clientID, userName); }
private void initialize(ChannelHandlerContext ctx) { // Avoid the case where destroy() is called before scheduling timeouts. // See: https://github.com/netty/netty/issues/143 if (LOG.isDebugEnabled()) { LOG.debug("Initializing autoflush handler on channel {} Cid: {}", ctx.channel(), NettyUtils.clientID(ctx.channel())); } switch (state) { case 1: case 2: return; } state = 1; EventExecutor loop = ctx.executor(); lastWriteTime = System.nanoTime(); writerIdleTimeout = loop.schedule(new WriterIdleTimeoutTask(ctx), writerIdleTimeNanos, TimeUnit.NANOSECONDS); }
void processSubscribe(MqttSubscribeMessage msg) { final String clientID = NettyUtils.clientID(channel); if (!connected) { LOG.warn("SUBSCRIBE received on already closed connection, CId={}, channel: {}", clientID, channel); dropConnection(); return; } postOffice.subscribeClientToTopics(msg, clientID, NettyUtils.userName(channel), this); }
private void processUnsubscribe(MqttUnsubscribeMessage msg) { List<String> topics = msg.payload().topics(); String clientID = NettyUtils.clientID(channel); LOG.trace("Processing UNSUBSCRIBE message. CId={}, topics: {}", clientID, topics); postOffice.unsubscribe(topics, this, msg.variableHeader().messageId()); }
private void initializeKeepAliveTimeout(Channel channel, MqttConnectMessage msg, String clientId) { int keepAlive = msg.variableHeader().keepAliveTimeSeconds(); NettyUtils.keepAlive(channel, keepAlive); NettyUtils.cleanSession(channel, msg.variableHeader().isCleanSession()); NettyUtils.clientID(channel, clientId); int idleTime = Math.round(keepAlive * 1.5f); setIdleTime(channel.pipeline(), idleTime); LOG.debug("Connection has been configured CId={}, keepAlive={}, removeTemporaryQoS2={}, idleTime={}", clientId, keepAlive, msg.variableHeader().isCleanSession(), idleTime); }
void handleConnectionLost() { String clientID = NettyUtils.clientID(channel); if (clientID == null || clientID.isEmpty()) { return; } LOG.info("Notifying connection lost event. CId: {}, channel: {}", clientID, channel); Session session = sessionRegistry.retrieve(clientID); if (session.hasWill()) { postOffice.fireWill(session.getWill()); } if (session.isClean()) { sessionRegistry.remove(clientID); } else { sessionRegistry.disconnect(clientID); } connected = false; //dispatch connection lost to intercept. String userName = NettyUtils.userName(channel); postOffice.dispatchConnectionLost(clientID,userName); LOG.trace("dispatch disconnection: clientId={}, userName={}", clientID, userName); }
setupInflightResender(channel); NettyUtils.clientID(channel, clientId); LOG.trace("CONNACK sent, channel: {}", channel); postOffice.dispatchConnection(msg);
String clientID = NettyUtils.clientID(ctx.channel()); MqttMessageType messageType = msg.fixedHeader().messageType(); switch (messageType) {
protected void subscribe(EmbeddedChannel channel, String topic, MqttQoS desiredQos) { MqttSubscribeMessage subscribe = MqttMessageBuilders.subscribe() .addSubscription(desiredQos, topic) .messageId(1) .build(); sut.subscribeClientToTopics(subscribe, FAKE_CLIENT_ID, null, connection); MqttSubAckMessage subAck = channel.readOutbound(); assertEquals(desiredQos.value(), (int) subAck.payload().grantedQoSLevels().get(0)); final String clientId = NettyUtils.clientID(channel); Subscription expectedSubscription = new Subscription(clientId, new Topic(topic), desiredQos); final Set<Subscription> matchedSubscriptions = subscriptions.matchWithoutQosSharpening(new Topic(topic)); assertEquals(1, matchedSubscriptions.size()); final Subscription onlyMatchedSubscription = matchedSubscriptions.iterator().next(); assertEquals(expectedSubscription, onlyMatchedSubscription); }
@Test public void testConnAckContainsSessionPresentFlag() { MqttConnectMessage msg = connMsg.clientId(FAKE_CLIENT_ID) .protocolVersion(MqttVersion.MQTT_3_1_1) .build(); NettyUtils.clientID(channel, FAKE_CLIENT_ID); NettyUtils.cleanSession(channel, false); // Connect a first time sut.bindToSession(connection, msg, FAKE_CLIENT_ID); // disconnect sut.disconnect(FAKE_CLIENT_ID); // Exercise, reconnect EmbeddedChannel anotherChannel = new EmbeddedChannel(); MQTTConnection anotherConnection = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZEROBYTE_CLIENT_ID, anotherChannel); sut.bindToSession(anotherConnection, msg, FAKE_CLIENT_ID); // Verify assertEqualsConnAck(CONNECTION_ACCEPTED, anotherChannel.readOutbound()); assertTrue("Connection is accepted and therefore should remain open", anotherChannel.isOpen()); }