问题
I'm trying to test MQTT-SN.
I'm using Mosquitto Broker, Paho MQTT-SN Gateway and this library (https://github.com/S3ler/arduino-mqtt-sn-client) for the clients.
I'm using an esp8266 as a client.
With this client, I can connect, subscribe, receive from subscribed topics but I cant publish into topics
memset(buffer, 0x0, buffer_length);
mqttSnClient.publish(buffer, publishTopicName , qos);
Every time I try to publish with this client, Mosquitto gives me
Socket error on client <clientid>, disconnecting
And my client disconnects from the Broker.
Any clues?
EDIT1
Client Code
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "WiFiUdpSocket.h"
#include "MqttSnClient.h"
#include <NTPClient.h>
const char* ssid = "example";
const char* password = "example1";
long utcOffsetInSeconds = -10800;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
#define buffer_length 10
char buffer[buffer_length + 1];
uint16_t buffer_pos = 0;
IPAddress gatewayIPAddress(192, 168, 0, 106);
uint16_t localUdpPort = 10000;
WiFiUDP udp;
WiFiUdpSocket wiFiUdpSocket(udp, localUdpPort);
MqttSnClient<WiFiUdpSocket> mqttSnClient(wiFiUdpSocket);
const char* clientId = "hamilton12";
char* subscribeTopicName = "ESP8266/123";
char* publishTopicName = "ESP8266/123";
int8_t qos = 1;
void mqttsn_callback(char *topic, uint8_t *payload, uint16_t length, bool retain) {
timeClient.update();
Serial.print("Received - Topic: ");
Serial.print(topic);
Serial.print(" Payload: ");
for (uint16_t i = 0; i < length; i++) {
char c = (char) * (payload + i);
Serial.print(c);
}
Serial.print(" Lenght: ");
Serial.print(length);
Serial.print(" Received Timestamp milliseconds: ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());
}
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
/* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
would try to act as both a client and an access-point and could cause
network-issues with your other WiFi-devices on your WiFi-network. */
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("Starting MqttSnClient - ");
mqttSnClient.setCallback(mqttsn_callback);
if (!mqttSnClient.begin()) {
Serial.print("Could not initialize MQTT-SN Client ");
while (true) {
Serial.println(".");
delay(1000);
}
}
Serial.println(" ready!");
}
void convertIPAddressAndPortToDeviceAddress(IPAddress& source, uint16_t port, device_address& target) {
// IPAdress 0 - 3 bytes
target.bytes[0] = source[0];
target.bytes[1] = source[1];
target.bytes[2] = source[2];
target.bytes[3] = source[3];
// Port 4 - 5 bytes
target.bytes[4] = port >> 8;
target.bytes[5] = (uint8_t) port ;
}
void loop() {
if (!mqttSnClient.is_mqttsn_connected()) {
#if defined(gatewayHostAddress)
IPAddress gatewayIPAddress;
if (!WiFi.hostByName(gatewayHostAddress, gatewayIPAddress, 20000)) {
Serial.println("Could not lookup MQTT-SN Gateway.");
return;
}
#endif
device_address gateway_device_address;
convertIPAddressAndPortToDeviceAddress(gatewayIPAddress, localUdpPort, gateway_device_address);
Serial.print("MQTT-SN Gateway device_address: ");
printDeviceAddress(&gateway_device_address);
if (!mqttSnClient.connect(&gateway_device_address, clientId, 180) ) {
Serial.println("Could not connect MQTT-SN Client.");
delay(1000);
return;
}
Serial.println("MQTT-SN Client connected.");
//mqttSnClient.set_mqttsn_connected();
if (!mqttSnClient.subscribe(subscribeTopicName, qos)){
Serial.println("Cant subscribe");
}
Serial.println("Subscribed");
}
//It never enters this IF
if (Serial.available() > 0) {
buffer[buffer_pos++] = Serial.read();
if (buffer[buffer_pos - 1] == '\n') {
// only qos -1, 0, 1 are supported
if (!mqttSnClient.publish(buffer, publishTopicName , qos)) {
Serial.println("Could not publish");
}
Serial.println("Published");
memset(buffer, 0x0, buffer_length);
buffer_pos = 0;
}
}
//Uncommenting this line will give socket error
//mqttSnClient.publish(buffer, publishTopicName , qos);
mqttSnClient.loop();
}
etc/mosquitto/mosquitto.conf
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
#include_dir /etc/mosquitto/conf.d
connection_messages true
log_timestamp true
log_dest stderr
log_type error
log_type warning
log_type debug
allow_anonymous true
gateway.conf
BrokerName=192.168.0.106
BrokerPortNo=1883
BrokerSecurePortNo=8883
#
# When AggregatingGateway=YES or ClientAuthentication=YES,
# All clients must be specified by the ClientList File
#
ClientAuthentication=NO
AggregatingGateway=NO
QoS-1=NO
Forwarder=NO
#ClientsList=/path/to/your_clients.conf
PredefinedTopic=NO
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
#RootCApath=/etc/ssl/certs/
#CertsFile=/path/to/certKey.pem
#PrivateKey=/path/to/privateKey.pem
GatewayID=1
GatewayName=PahoGateway-01
KeepAlive=900
#LoginID=your_ID
#Password=your_Password
# UDP
GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1884
# UDP6
GatewayUDP6Bind=FFFF:FFFE::1
GatewayUDP6Port=10000
GatewayUDP6Broadcast=FF02::1
GatewayUDP6If=wpan0
# XBee
Baudrate=38400
SerialDevice=/dev/ttyUSB0
ApiMode=2
# LOG
ShearedMemory=NO;
EDIT2
Terminal running mosquitto
hamilton@hamilton-note:~$ mosquitto
1574806892: mosquitto version 1.4.15 (build date Tue, 18 Jun 2019 11:42:22 -0300) starting
1574806892: Using default config.
1574806892: Opening ipv4 listen socket on port 1883.
1574806892: Opening ipv6 listen socket on port 1883.
1574806900: New connection from 192.168.0.106 on port 1883.
1574806900: New client connected from 192.168.0.106 as hamilton123 (c1, k46080).
1574806900: Socket error on client hamilton123, disconnecting.
^C1574806911: mosquitto version 1.4.15 terminating
Terminal running Paho Gateway
hamilton@hamilton-note:~/Downloads$ ./MQTT-SNGateway
***************************************************************************
* MQTT-SN Transparent Gateway
* Part of Project Paho in Eclipse
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
*
* Author : Tomoaki YAMAGUCHI
* Version: 1.3.1
***************************************************************************
20191126 192134.372 PahoGateway-01 has been started.
ConfigFile: ./gateway.conf
PreDefFile: ./predefinedTopic.conf
SensorN/W: UDP Multicast 225.1.1.1:1884 Gateway Port 10000
Broker: 192.168.0.106 : 1883, 8883
RootCApath: (null)
RootCAfile: (null)
CertKey: (null)
PrivateKey: (null)
20191126 192140.660 CONNECT <--- hamilton123 12 04 04 01 B4 00 68 61 6D 69 6C 74 6F 6E 31 32 33 00
20191126 192140.660 CONNECT ===> hamilton123 10 17 00 04 4D 51 54 54 04 02 B4 00 00 0B 68 61 6D 69 6C 74 6F 6E 31 32 33
20191126 192140.874 CONNACK <=== hamilton123 20 02 00 00
20191126 192140.874 CONNACK ---> hamilton123 03 05 00
20191126 192140.879 SUBSCRIBE 0200 <--- hamilton123 11 12 20 02 00 45 53 50 38 32 36 36 2F 31 32 33 00
20191126 192140.879 SUBSCRIBE 0200 ===> hamilton123 82 10 02 00 00 0B 45 53 50 38 32 36 36 2F 31 32 33 01
20191126 192140.879 SUBACK 0200 <=== hamilton123 90 03 02 00 01
20191126 192140.879 SUBACK 0200 ---> hamilton123 08 13 20 00 01 02 00 00
20191126 192140.883 PUBLISH 0300 <--- hamilton123 08 0C 22 00 01 03 00 00
20191126 192140.884 PUBLISH 0300 ===> hamilton123 32 07 00 02 00 01 03 00 00
^C20191126 192149.215 BrokerSendTask stopped.
20191126 192149.215 PacketHandleTask stopped.
20191126 192149.215 ClientSendTask stopped.
20191126 192149.386 BrokerRecvTask stopped.
20191126 192150.158 ClientRecvTask stopped.
20191126 192150.215 MQTT-SN Gateway stoped
回答1:
Thank you for the help Dalton Cézane.
But I found the problem in an open issue in the client's library:
Having trouble with your example WiFiUdpMqttSnClient program in that it does not successfully publish the test messages. I'm using paho-mqtt-sn gateway.
I'm bashing around in the dark a bit but I think this is because it publishes the messages with the flag TopicIdType set to 2. I think it should be zero (normal) because it's not pre-registered nor is it a short topic.
In file MqttSnClient.h line 216 the call to send_publish has short_topic set to true. But that's not all; in file mqttsn_messages.h around line 215 if short_topic flag is false it sets the flag to predefined. I've removed the latter 'else' clause so the flag is set to zero and I can now publish successfully.
I suspect my hack is not a complete solution but I hope it helps you resolve this issue.
This comment was made by @nottledim, big thanks!
Now i can publish without a problem using my esp8266.
Just leaving here if anyone has this problem.
link to the issue: https://github.com/S3ler/arduino-mqtt-sn-client/issues/3
来源:https://stackoverflow.com/questions/59039420/socket-error-on-client-disconnecting-with-paho-mqtt-sn-gateway-and-esp8266-c