Switched from Moquette's MQTT codec to Netty's MQTT codec ones
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
package io.moquette.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.moquette.connections.IConnectionsManager;
|
||||
import io.moquette.connections.MqttConnectionMetrics;
|
||||
import io.moquette.connections.MqttSession;
|
||||
import io.moquette.connections.MqttSubscription;
|
||||
import io.moquette.parser.proto.messages.AbstractMessage;
|
||||
import io.moquette.server.netty.metrics.BytesMetrics;
|
||||
import io.moquette.server.netty.metrics.MessageMetrics;
|
||||
import io.moquette.spi.ClientSession;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||
import io.netty.handler.codec.mqtt.MqttMessage;
|
||||
import io.netty.handler.codec.mqtt.MqttMessageType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
|
||||
@@ -27,38 +27,29 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
private final ISessionsStore sessionsStore;
|
||||
|
||||
public ConnectionDescriptorStore(ISessionsStore sessionsStore) {
|
||||
this.connectionDescriptors = new ConcurrentHashMap<String, ConnectionDescriptor>();
|
||||
this.connectionDescriptors = new ConcurrentHashMap<>();
|
||||
this.sessionsStore = sessionsStore;
|
||||
}
|
||||
|
||||
public boolean sendMessage(AbstractMessage message, String clientId) {
|
||||
return sendMessage(message, null, clientId);
|
||||
}
|
||||
|
||||
public boolean sendMessage(AbstractMessage message, Integer messageID, String clientID) {
|
||||
public boolean sendMessage(MqttMessage message, Integer messageID, String clientID) {
|
||||
final MqttMessageType messageType = message.fixedHeader().messageType();
|
||||
try {
|
||||
// The connection descriptors map will never be null: it's a final
|
||||
// attribute.
|
||||
|
||||
if (messageID != null) {
|
||||
LOG.info("Sending {} message. MqttClientId = {}, messageId = {}.", message.getMessageType(), clientID,
|
||||
messageID);
|
||||
LOG.info("Sending {} message CId=<{}>, messageId={}", messageType, clientID, messageID);
|
||||
} else {
|
||||
LOG.debug("Sending {} message. MqttClientId = {}.", message.getMessageType(), clientID);
|
||||
LOG.debug("Sending {} message CId=<{}>", messageType, clientID);
|
||||
}
|
||||
|
||||
ConnectionDescriptor descriptor = connectionDescriptors.get(clientID);
|
||||
if (descriptor == null) {
|
||||
if (messageID != null) {
|
||||
LOG.error(
|
||||
"The client has just disconnected. The {} message could not be sent. MqttClientId = {}, messageId = {}.",
|
||||
message.getMessageType(), clientID, messageID);
|
||||
LOG.error("Client has just disconnected. The {} message could not be sent. CId=<{}>, messageId={}",
|
||||
messageType, clientID, messageID);
|
||||
} else {
|
||||
LOG.error("The client has just disconnected. The {} could not be sent. MqttClientId = {}.",
|
||||
message.getMessageType(), clientID);
|
||||
LOG.error("Client has just disconnected. The {} could not be sent. CId=<{}>", messageType, clientID);
|
||||
}
|
||||
/*
|
||||
* If the client hast just disconnected, its connection
|
||||
* If the client has just disconnected, its connection
|
||||
* descriptor will be null. We don't have to make the broker
|
||||
* crash: we'll just discard the PUBACK message.
|
||||
*/
|
||||
@@ -67,14 +58,11 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
descriptor.writeAndFlush(message);
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
String errorMsg = "Unable to send " + messageType + " message. CId=<" + clientID + ">";
|
||||
if (messageID != null) {
|
||||
LOG.error(
|
||||
"Unable to send {} message. MqttClientId = {}, messageId = {}, cause = {}, errorMessage = {}.",
|
||||
message.getMessageType(), clientID, messageID, e.getCause(), e.getMessage());
|
||||
} else {
|
||||
LOG.error("Unable to send {} message. MqttClientId = {}, cause = {}, errorMessage = {}.",
|
||||
message.getMessageType(), clientID, e.getCause(), e.getMessage());
|
||||
errorMsg += ", messageId=" + messageID;
|
||||
}
|
||||
LOG.error(errorMsg, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -111,7 +99,7 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
ConnectionDescriptor descriptor = connectionDescriptors.get(clientID);
|
||||
if (descriptor == null) {
|
||||
LOG.error(
|
||||
"The connection descriptor doesn't exist. The MQTT connection cannot be closed. MqttClientId = {}, closeImmediately = {}.",
|
||||
"The connection descriptor doesn't exist. The MQTT connection cannot be closed. CId=<{}>, closeImmediately = {}.",
|
||||
clientID, closeImmediately);
|
||||
return false;
|
||||
}
|
||||
@@ -125,10 +113,10 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
|
||||
@Override
|
||||
public MqttSession getSessionStatus(String clientID) {
|
||||
LOG.info("Retrieving status of session. MqttClientId = {}.", clientID);
|
||||
LOG.info("Retrieving status of session. CId=<{}>", clientID);
|
||||
ClientSession session = sessionsStore.sessionForClient(clientID);
|
||||
if (session == null) {
|
||||
LOG.error("The given MQTT client ID doesn't have an associated session. MqttClientId = {}.", clientID);
|
||||
LOG.error("The given MQTT client ID doesn't have an associated session. CId=<{}>", clientID);
|
||||
return null;
|
||||
}
|
||||
return buildMqttSession(session);
|
||||
@@ -166,7 +154,7 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
|
||||
result.setPendingPublishMessagesNo(session.getPendingPublishMessagesNo());
|
||||
result.setSecondPhaseAckPendingMessages(session.getSecondPhaseAckPendingMessages());
|
||||
result.setInflightMessages(session.getInflightMessagesNo());
|
||||
LOG.info("The status of the session has been retrieved successfully. MqttClientId = {}.", session.clientID);
|
||||
LOG.info("The status of the session has been retrieved successfully. CId=<{}>", session.clientID);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,12 @@ package io.moquette.server;
|
||||
import com.hazelcast.core.Message;
|
||||
import com.hazelcast.core.MessageListener;
|
||||
import io.moquette.interception.HazelcastMsg;
|
||||
import io.moquette.parser.proto.messages.AbstractMessage;
|
||||
import io.moquette.parser.proto.messages.PublishMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Created by mackristof on 28/05/2016.
|
||||
*/
|
||||
@@ -29,13 +28,14 @@ public class HazelcastListener implements MessageListener<HazelcastMsg> {
|
||||
HazelcastMsg hzMsg = msg.getMessageObject();
|
||||
LOG.info("{} received from hazelcast for topic {} message: {}", hzMsg.getClientId(),
|
||||
hzMsg.getTopic(), hzMsg.getPayload());
|
||||
PublishMessage publishMessage = new PublishMessage();
|
||||
publishMessage.setTopicName(hzMsg.getTopic());
|
||||
publishMessage.setQos(AbstractMessage.QOSType.valueOf(hzMsg.getQos()));
|
||||
publishMessage.setPayload(ByteBuffer.wrap(hzMsg.getPayload()));
|
||||
publishMessage.setLocal(false);
|
||||
publishMessage.setClientId(hzMsg.getClientId());
|
||||
server.internalPublish(publishMessage);
|
||||
//TODO pass forward this information in somehow publishMessage.setLocal(false);
|
||||
|
||||
MqttQoS qos = MqttQoS.valueOf(hzMsg.getQos());
|
||||
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, false, 0);
|
||||
MqttPublishVariableHeader varHeader = new MqttPublishVariableHeader(hzMsg.getTopic(), 0);
|
||||
ByteBuf payload = Unpooled.wrappedBuffer(hzMsg.getPayload());
|
||||
MqttPublishMessage publishMessage = new MqttPublishMessage(fixedHeader, varHeader, payload);
|
||||
server.internalPublish(publishMessage, hzMsg.getClientId());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOG.error("error polling hazelcast msg queue", ex);
|
||||
|
||||
@@ -27,15 +27,15 @@ import io.moquette.connections.IConnectionsManager;
|
||||
import io.moquette.interception.HazelcastInterceptHandler;
|
||||
import io.moquette.interception.HazelcastMsg;
|
||||
import io.moquette.interception.InterceptHandler;
|
||||
import io.moquette.parser.proto.messages.PublishMessage;
|
||||
import io.moquette.server.config.*;
|
||||
import io.moquette.spi.impl.ProtocolProcessorBootstrapper;
|
||||
import io.moquette.server.netty.NettyAcceptor;
|
||||
import io.moquette.spi.impl.ProtocolProcessor;
|
||||
import io.moquette.spi.impl.ProtocolProcessorBootstrapper;
|
||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||
import io.moquette.spi.security.IAuthenticator;
|
||||
import io.moquette.spi.security.IAuthorizator;
|
||||
import io.moquette.spi.security.ISslContextCreator;
|
||||
import io.netty.handler.codec.mqtt.MqttPublishMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -221,16 +221,18 @@ public class Server {
|
||||
* It can be used only after the server is correctly started with startServer.
|
||||
*
|
||||
* @param msg the message to forward.
|
||||
* @param clientId the id of the sending server.
|
||||
* @throws IllegalStateException if the server is not yet started
|
||||
* */
|
||||
public void internalPublish(PublishMessage msg) {
|
||||
public void internalPublish(MqttPublishMessage msg, final String clientId) {
|
||||
final int messageID = msg.variableHeader().messageId();
|
||||
if (!m_initialized) {
|
||||
LOG.error("The server is not started. The message cannot be published. MqttClientId = {}, messageId = {}.",
|
||||
msg.getClientId(), msg.getMessageID());
|
||||
LOG.error("The server is not started. The message cannot be published. MqttClientId = {}, messageId = {}",
|
||||
clientId, messageID);
|
||||
throw new IllegalStateException("Can't publish on a server is not yet started");
|
||||
}
|
||||
LOG.debug("Publishing message. MqttClientId = {}, messageId = {}.", msg.getClientId(), msg.getMessageID());
|
||||
m_processor.internalPublish(msg);
|
||||
LOG.debug("Publishing message. MqttClientId = {}, messageId = {}", clientId, messageID);
|
||||
m_processor.internalPublish(msg, clientId);
|
||||
}
|
||||
|
||||
public void stopServer() {
|
||||
@@ -266,7 +268,6 @@ public class Server {
|
||||
/**
|
||||
* SPI method used by Broker embedded applications to add intercept handlers.
|
||||
* @param interceptHandler the handler to add.
|
||||
* @return true id operation was successful.
|
||||
* */
|
||||
public void addInterceptHandler(InterceptHandler interceptHandler) {
|
||||
if (!m_initialized) {
|
||||
@@ -282,7 +283,6 @@ public class Server {
|
||||
/**
|
||||
* SPI method used by Broker embedded applications to remove intercept handlers.
|
||||
* @param interceptHandler the handler to remove.
|
||||
* @return true id operation was successful.
|
||||
* */
|
||||
public void removeInterceptHandler(InterceptHandler interceptHandler) {
|
||||
if (!m_initialized) {
|
||||
@@ -297,7 +297,7 @@ public class Server {
|
||||
/**
|
||||
* Returns the connections manager of this broker.
|
||||
*
|
||||
* @return
|
||||
* @return IConnectionsManager the instance used bt the broker.
|
||||
*/
|
||||
public IConnectionsManager getConnectionsManager() {
|
||||
return m_processorBootstrapper.getConnectionDescriptors();
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2017 The original author or authorsgetRockQuestions()
|
||||
* ------------------------------------------------------
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Apache License v2.0 which accompanies this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* The Apache License v2.0 is available at
|
||||
* http://www.opensource.org/licenses/apache2.0.php
|
||||
*
|
||||
* You may elect to redistribute this code under either of these licenses.
|
||||
*/
|
||||
package io.moquette.server.netty;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MessageBuilder {
|
||||
|
||||
public static class PublishBuilder {
|
||||
private String topic = null;
|
||||
private boolean retained = false;
|
||||
private MqttQoS qos;
|
||||
private byte[] payload;
|
||||
private int messageId = 0;
|
||||
|
||||
public PublishBuilder topicName(String topic) {
|
||||
this.topic = topic;
|
||||
return PublishBuilder.this;
|
||||
}
|
||||
|
||||
public PublishBuilder retained(boolean retained) {
|
||||
this.retained = retained;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublishBuilder qos(MqttQoS qos) {
|
||||
this.qos = qos;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublishBuilder payload(byte[] payload) {
|
||||
this.payload = payload;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PublishBuilder messageId(int messageId) {
|
||||
this.messageId = messageId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttPublishMessage build() {
|
||||
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retained, 0);
|
||||
MqttPublishVariableHeader mqttVariableHeader = new MqttPublishVariableHeader(topic, messageId);
|
||||
return new MqttPublishMessage(mqttFixedHeader, mqttVariableHeader, Unpooled.buffer().writeBytes(payload));
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConnectBuilder {
|
||||
|
||||
private MqttVersion version = MqttVersion.MQTT_3_1_1;
|
||||
private String clientId;
|
||||
private boolean cleanSession = false;
|
||||
private boolean hasUser = false;
|
||||
private boolean hasPassword = false;
|
||||
private int keepAliveSecs;
|
||||
private boolean willFlag = false;
|
||||
private MqttQoS willQos = MqttQoS.AT_MOST_ONCE;
|
||||
private String willTopic = null;
|
||||
private String willMessage = null;
|
||||
private String username = null;
|
||||
private String password = null;
|
||||
|
||||
public ConnectBuilder protocolVersion(MqttVersion version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder clientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder cleanSession(boolean cleanSession) {
|
||||
this.cleanSession = cleanSession;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder keepAlive(int keepAliveSecs) {
|
||||
this.keepAliveSecs = keepAliveSecs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder willFlag(boolean willFlag) {
|
||||
this.willFlag = willFlag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder willQoS(MqttQoS willQos) {
|
||||
this.willQos = willQos;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder willTopic(String willTopic) {
|
||||
this.willTopic = willTopic;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder willMessage(String willMessage) {
|
||||
this.willMessage = willMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder hasUser() {
|
||||
this.hasUser = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder hasPassword() {
|
||||
this.hasPassword = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder username(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder password(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttConnectMessage build() {
|
||||
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.CONNECT, false, MqttQoS.AT_MOST_ONCE, false, 0);
|
||||
MqttConnectVariableHeader mqttConnectVariableHeader =
|
||||
new MqttConnectVariableHeader(
|
||||
version.protocolName(),
|
||||
version.protocolLevel(),
|
||||
hasUser,
|
||||
hasPassword,
|
||||
false,
|
||||
willQos.value(),
|
||||
willFlag,
|
||||
cleanSession,
|
||||
keepAliveSecs);
|
||||
MqttConnectPayload mqttConnectPayload = new MqttConnectPayload(clientId, willTopic, willMessage, username, password);
|
||||
return new MqttConnectMessage(mqttFixedHeader, mqttConnectVariableHeader, mqttConnectPayload);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SubscribeBuilder {
|
||||
|
||||
private List<MqttTopicSubscription> subscriptions = new ArrayList<>();
|
||||
private int messageId;
|
||||
|
||||
public SubscribeBuilder addSubscription(MqttQoS qos, String topic) {
|
||||
subscriptions.add(new MqttTopicSubscription(topic, qos));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SubscribeBuilder messageId(int messageId) {
|
||||
this.messageId = messageId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttSubscribeMessage build() {
|
||||
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.SUBSCRIBE, false, MqttQoS.AT_LEAST_ONCE, false, 0);
|
||||
MqttMessageIdVariableHeader mqttVariableHeader = MqttMessageIdVariableHeader.from(messageId);
|
||||
MqttSubscribePayload mqttSubscribePayload = new MqttSubscribePayload(subscriptions);
|
||||
return new MqttSubscribeMessage(mqttFixedHeader, mqttVariableHeader, mqttSubscribePayload);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnsubscribeBuilder {
|
||||
|
||||
private List<String> topicFilters = new ArrayList<>();
|
||||
private int messageId = 0;
|
||||
|
||||
public UnsubscribeBuilder addTopicFilter(String topic) {
|
||||
topicFilters.add(topic);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UnsubscribeBuilder messageId(int messageId) {
|
||||
this.messageId = messageId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttUnsubscribeMessage build() {
|
||||
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.UNSUBSCRIBE, false,
|
||||
MqttQoS.AT_LEAST_ONCE, false, 0);
|
||||
MqttMessageIdVariableHeader mqttVariableHeader = MqttMessageIdVariableHeader.from(messageId);
|
||||
MqttUnsubscribePayload mqttSubscribePayload = new MqttUnsubscribePayload(topicFilters);
|
||||
return new MqttUnsubscribeMessage(mqttFixedHeader, mqttVariableHeader, mqttSubscribePayload);
|
||||
}
|
||||
}
|
||||
|
||||
public static ConnectBuilder connect() {
|
||||
return new ConnectBuilder();
|
||||
}
|
||||
|
||||
public static PublishBuilder publish() {
|
||||
return new PublishBuilder();
|
||||
}
|
||||
|
||||
public static SubscribeBuilder subscribe() {
|
||||
return new SubscribeBuilder();
|
||||
}
|
||||
|
||||
public static UnsubscribeBuilder unsubscribe() {
|
||||
return new UnsubscribeBuilder();
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,11 @@
|
||||
package io.moquette.server.netty;
|
||||
|
||||
import io.moquette.BrokerConstants;
|
||||
import static io.moquette.BrokerConstants.*;
|
||||
import io.moquette.parser.netty.MQTTDecoder;
|
||||
import io.moquette.parser.netty.MQTTEncoder;
|
||||
import io.moquette.spi.security.ISslContextCreator;
|
||||
import io.moquette.server.ServerAcceptor;
|
||||
import io.moquette.server.config.IConfig;
|
||||
import io.moquette.server.netty.metrics.*;
|
||||
import io.moquette.spi.impl.ProtocolProcessor;
|
||||
import io.moquette.spi.security.ISslContextCreator;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.*;
|
||||
@@ -38,6 +35,8 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
import io.netty.handler.codec.mqtt.MqttDecoder;
|
||||
import io.netty.handler.codec.mqtt.MqttEncoder;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.concurrent.Future;
|
||||
@@ -50,6 +49,8 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.moquette.BrokerConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author andrea
|
||||
@@ -179,8 +180,8 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
// pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MQTTDecoder());
|
||||
pipeline.addLast("encoder", new MQTTEncoder());
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
@@ -213,8 +214,8 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, nettyChannelTimeoutSeconds));
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MQTTDecoder());
|
||||
pipeline.addLast("encoder", new MQTTEncoder());
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
@@ -247,8 +248,8 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
//pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MQTTDecoder());
|
||||
pipeline.addLast("encoder", new MQTTEncoder());
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
@@ -283,8 +284,8 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, nettyChannelTimeoutSeconds));
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MQTTDecoder());
|
||||
pipeline.addLast("encoder", new MQTTEncoder());
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
|
||||
@@ -15,18 +15,16 @@
|
||||
*/
|
||||
package io.moquette.server.netty;
|
||||
|
||||
import io.moquette.parser.proto.Utils;
|
||||
import io.moquette.parser.proto.messages.*;
|
||||
import io.moquette.spi.impl.ProtocolProcessor;
|
||||
import static io.moquette.parser.proto.messages.AbstractMessage.*;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
|
||||
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -44,47 +42,46 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object message) {
|
||||
AbstractMessage msg = (AbstractMessage) message;
|
||||
String messageType = Utils.msgType2String(msg.getMessageType());
|
||||
LOG.debug("Processing MQTT message. MessageType = {}.", messageType);
|
||||
MqttMessage msg = (MqttMessage) message;
|
||||
MqttMessageType messageType = msg.fixedHeader().messageType();
|
||||
LOG.debug("Processing MQTT message, type={}", messageType);
|
||||
try {
|
||||
switch (msg.getMessageType()) {
|
||||
switch (messageType) {
|
||||
case CONNECT:
|
||||
m_processor.processConnect(ctx.channel(), (ConnectMessage) msg);
|
||||
m_processor.processConnect(ctx.channel(), (MqttConnectMessage) msg);
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
m_processor.processSubscribe(ctx.channel(), (SubscribeMessage) msg);
|
||||
m_processor.processSubscribe(ctx.channel(), (MqttSubscribeMessage) msg);
|
||||
break;
|
||||
case UNSUBSCRIBE:
|
||||
m_processor.processUnsubscribe(ctx.channel(), (UnsubscribeMessage) msg);
|
||||
m_processor.processUnsubscribe(ctx.channel(), (MqttUnsubscribeMessage) msg);
|
||||
break;
|
||||
case PUBLISH:
|
||||
m_processor.processPublish(ctx.channel(), (PublishMessage) msg);
|
||||
m_processor.processPublish(ctx.channel(), (MqttPublishMessage) msg);
|
||||
break;
|
||||
case PUBREC:
|
||||
m_processor.processPubRec(ctx.channel(), (PubRecMessage) msg);
|
||||
m_processor.processPubRec(ctx.channel(), msg);
|
||||
break;
|
||||
case PUBCOMP:
|
||||
m_processor.processPubComp(ctx.channel(), (PubCompMessage) msg);
|
||||
m_processor.processPubComp(ctx.channel(), msg);
|
||||
break;
|
||||
case PUBREL:
|
||||
m_processor.processPubRel(ctx.channel(), (PubRelMessage) msg);
|
||||
m_processor.processPubRel(ctx.channel(), msg);
|
||||
break;
|
||||
case DISCONNECT:
|
||||
m_processor.processDisconnect(ctx.channel());
|
||||
break;
|
||||
case PUBACK:
|
||||
m_processor.processPubAck(ctx.channel(), (PubAckMessage) msg);
|
||||
m_processor.processPubAck(ctx.channel(), (MqttPubAckMessage) msg);
|
||||
break;
|
||||
case PINGREQ:
|
||||
PingRespMessage pingResp = new PingRespMessage();
|
||||
MqttFixedHeader pingHeader = new MqttFixedHeader(MqttMessageType.PINGRESP, false, AT_MOST_ONCE, false, 0);
|
||||
MqttMessage pingResp = new MqttMessage(pingHeader);
|
||||
ctx.writeAndFlush(pingResp);
|
||||
break;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOG.error(
|
||||
"An unexpected exception was caught while processing MQTT message. MessageType = {}, cause = {}, errorMessage = {}.",
|
||||
messageType, ex.getCause(), ex.getMessage());
|
||||
LOG.error("Exception was caught while processing MQTT message, " + ex.getCause(), ex);
|
||||
ctx.fireExceptionCaught(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
package io.moquette.server.netty.metrics;
|
||||
|
||||
import io.moquette.parser.proto.messages.*;
|
||||
import io.moquette.server.netty.NettyUtils;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.moquette.parser.proto.messages.AbstractMessage.*;
|
||||
import static io.moquette.spi.impl.Utils.messageId;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,46 +42,42 @@ public class MQTTMessageLogger extends ChannelDuplexHandler {
|
||||
}
|
||||
|
||||
private void logMQTTMessage(ChannelHandlerContext ctx, Object message, String direction) {
|
||||
if (!(message instanceof AbstractMessage)) {
|
||||
if (!(message instanceof MqttMessage)) {
|
||||
return;
|
||||
}
|
||||
AbstractMessage msg = (AbstractMessage) message;
|
||||
MqttMessage msg = (MqttMessage) message;
|
||||
String clientID = NettyUtils.clientID(ctx.channel());
|
||||
switch (msg.getMessageType()) {
|
||||
MqttMessageType messageType = msg.fixedHeader().messageType();
|
||||
switch (messageType) {
|
||||
case CONNECT:
|
||||
ConnectMessage connect = (ConnectMessage) msg;
|
||||
LOG.info("{} CONNECT client <{}>", direction, connect.getClientID());
|
||||
LOG.info("{} CONNECT client <{}>", direction, clientID);
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
SubscribeMessage subscribe = (SubscribeMessage) msg;
|
||||
LOG.info("{} SUBSCRIBE <{}> to topics {}", direction, clientID, subscribe.subscriptions());
|
||||
MqttSubscribeMessage subscribe = (MqttSubscribeMessage) msg;
|
||||
LOG.info("{} SUBSCRIBE <{}> to topics {}", direction, clientID, subscribe.payload().topicSubscriptions());
|
||||
break;
|
||||
case UNSUBSCRIBE:
|
||||
UnsubscribeMessage unsubscribe = (UnsubscribeMessage) msg;
|
||||
LOG.info("{} UNSUBSCRIBE <{}> to topics <{}>", direction, clientID, unsubscribe.topicFilters());
|
||||
MqttUnsubscribeMessage unsubscribe = (MqttUnsubscribeMessage) msg;
|
||||
LOG.info("{} UNSUBSCRIBE <{}> to topics <{}>", direction, clientID, unsubscribe.payload().topics());
|
||||
break;
|
||||
case PUBLISH:
|
||||
PublishMessage publish = (PublishMessage) msg;
|
||||
LOG.info("{} PUBLISH <{}> to topics <{}>", direction, clientID, publish.getTopicName());
|
||||
MqttPublishMessage publish = (MqttPublishMessage) msg;
|
||||
LOG.info("{} PUBLISH <{}> to topics <{}>", direction, clientID, publish.variableHeader().topicName());
|
||||
break;
|
||||
case PUBREC:
|
||||
PubRecMessage pubrec = (PubRecMessage) msg;
|
||||
LOG.info("{} PUBREC <{}> packetID <{}>", direction, clientID, pubrec.getMessageID());
|
||||
LOG.info("{} PUBREC <{}> packetID <{}>", direction, clientID, messageId(msg));
|
||||
break;
|
||||
case PUBCOMP:
|
||||
PubCompMessage pubCompleted = (PubCompMessage) msg;
|
||||
LOG.info("{} PUBCOMP <{}> packetID <{}>", direction, clientID, pubCompleted.getMessageID());
|
||||
LOG.info("{} PUBCOMP <{}> packetID <{}>", direction, clientID, messageId(msg));
|
||||
break;
|
||||
case PUBREL:
|
||||
PubRelMessage pubRelease = (PubRelMessage) msg;
|
||||
LOG.info("{} PUBREL <{}> packetID <{}>", direction, clientID, pubRelease.getMessageID());
|
||||
LOG.info("{} PUBREL <{}> packetID <{}>", direction, clientID, messageId(msg));
|
||||
break;
|
||||
case DISCONNECT:
|
||||
LOG.info("{} DISCONNECT <{}>", direction, clientID);
|
||||
break;
|
||||
case PUBACK:
|
||||
PubAckMessage pubAck = (PubAckMessage) msg;
|
||||
LOG.info("{} PUBACK <{}> packetID <{}>", direction, clientID, pubAck.getMessageID());
|
||||
LOG.info("{} PUBACK <{}> packetID <{}>", direction, clientID, messageId(msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -100,24 +96,4 @@ public class MQTTMessageLogger extends ChannelDuplexHandler {
|
||||
logMQTTMessage(ctx, msg, "C<-B");
|
||||
ctx.write(msg, promise);
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
// if (cause instanceof CorruptedFrameException) {
|
||||
// //something goes bad with decoding
|
||||
// LOG.warn("Error decoding a packet, probably a bad formatted packet, message: " + cause.getMessage());
|
||||
// } else {
|
||||
// LOG.error("Ugly error on networking", cause);
|
||||
// }
|
||||
// ctx.close();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
|
||||
// if (ctx.channel().isWritable()) {
|
||||
// m_processor.notifyChannelWritable(ctx.channel());
|
||||
// }
|
||||
// ctx.fireChannelWritabilityChanged();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user