NodeJs Server flooded with UDP Broadcasts, doesn't send response - javascript

I am building a system using an ESP8266/NodeMcu module (similar to an Arduino, just with networking capabilities) and a NodeJs server running on the local network.
To discover the IP address of the server, I'm trying to use UDP broadcasting on the NodeMcu module. The idea is to send out a message on the local broadcasting IP (e.g. 192.168.1.255). The server then receives the message and sends a response, confirming that it is the server. This way, the NodeMcu knows the direct address of the server for further communication.
The problem is, that the server is completely flooding itself with the same message whenever it receives the first message from the NodeMcu, while the NodeMcu actually sends out a message only once a second.
It looks like this on the NodeMcu side:
[UDP] Sending UDP Broadcast on IP: 192.168.43.255, Port: 8080, Message: ESP8266 UDP Server Discovery Broadcast
The server outputs something like this, many times a second:
[10:33:07] 127.0.0.1:8080 # service discovery : ESP8266 UDP Server Discovery Broadcast
[10:33:07] 127.0.0.1:8080 # service discovery : ESP8266 UDP Server Discovery Broadcast
[10:33:07] 127.0.0.1:8080 # service discovery : ESP8266 UDP Server Discovery Broadcast
It doesn't make sense that it's receiving that many messages, especially because it's apparently coming from 127.0.0.1 and not the IP of the NodeMcu. It also doesn't send out any response.
I tried to receive the broadcast on my phone with a UDP Monitor app, an application called Packet Sender and the Linux Terminal. It all worked fine, and sending a manual response triggered the acknowledgement on the NodeMcu.
So I'm thinking there has to be some kind of error with the server, or with the network I'm using. The server is running on Linux on my computer, while I'm hosting the network via a hotspot on my phone (my real WiFi network blocked UDP broadcasting). The Linux firewall is turned off.
I'm no expert in JavaScript or NodeJs by any means and the server was written by someone I'm working with, but he has no clue either. Anyway, this is the important part on the server:
client.on('listening', function () {
var address = client.address();
debugMessage(
format('Service discovery running on port %s', config.port)
);
client.setBroadcast(true);
});
client.on('message', function (message, rinfo) {
debugMessage(
format('%s:%s # service discovery : %s', rinfo.address, rinfo.port, message)
);
client.send(message, 0, message.length, rinfo.port, rinfo.ip);
});
client.bind(config.port);
The code on the NodeMcu looks like this:
#include <ESP8266WiFi.h> // WiFi library
#include <WiFiUdp.h> // UPD functionality
// UDP variables
WiFiUDP udp;
unsigned int localUdpPort = 8080;
char incomingPacket[255];
const char broadcastMessage[] = "ESP8266 UDP Server Discovery Broadcast";
// Server details - written to when the server is found
IPAddress serverIp = ~WiFi.subnetMask() | WiFi.gatewayIP(); // Use Broadcast Address as default in case the UDP service discovery isn't working as intended
unsigned int serverPort = localUdpPort; // Use local port as default in case the UDP service discovery ins't working as intended
void setupWiFi()
{
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
#if LOGGING
Serial.println("Connecting to network: " + (String) WIFI_SSID);
#endif
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
}
#if LOGGING
Serial.print("Connected to network, Local IP Address: ");
Serial.println(WiFi.localIP());
#endif
udp.begin(localUdpPort); // begin listening on UDP port
#if LOGGING
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
#endif LOGGING
}
// Discover the server via a UDP broadcast, and store it's IP and Port in the local network in field variables for later use
// IMPORTANT - For the server to work, the Linux Firewall has to be disabled!!!
void discoverServer()
{
changeColor(PURPLE, false); // change the color of the RGB status LED to signal that the program is searching for the server
bool serverFound = false; // stop when the server is found
IPAddress broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP(); // Get the Broadcast IP of the local network (e.g. 192.168.0.255)
while (!serverFound)
{
// Send UDP Broadcast
udp.beginPacket(broadcastIp, localUdpPort);
udp.write(broadcastMessage);
udp.endPacket();
#if LOGGING
Serial.printf("[UDP] Sending UDP Broadcast on IP: %s, Port: %d, Message: %s\n", broadcastIp.toString().c_str(), localUdpPort, broadcastMessage);
#endif
delay(1000); // Pause a few milliseconds to avoid flooding the network
// Receive UDP packets
int packetSize = udp.parsePacket();
if (packetSize > 0)
{
// Read incoming UDP Packet
int len = udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
#if LOGGING
Serial.printf("[UDP] Received %d bytes from %s, port %d\n", packetSize, udp.remoteIP().toString().c_str(), udp.remotePort());
Serial.printf("[UDP] Packet contents: %s\n", incomingPacket);
#endif
// Check if the received message is from the server we are searching for
if (strcmp(incomingPacket, broadcastMessage) == 0)
{
serverIp = udp.remoteIP();
serverPort = udp.remotePort();
#if LOGGING
Serial.printf("[UDP] Found Server on IP: %s, Port: %d\n", serverIp.toString().c_str(), serverPort);
#endif
serverFound = true;
changeColor(YELLOW, false); // Change status color of RGB LED back to yellow
}
}
}
}
I'm really wondering if there is something wrong with the server, the network or the NodeMcu. Especially because every other method I tried worked perfectly, just not when I'm sending it from the NodeMcu. Any help is very much appreciated!

It turned out that there was an error in the server code.
Instead of
client.send(message, 0, message.length, rinfo.port, rinfo.ip);
it should have been
client.send(message, 0, message.length, rinfo.port, rinfo.address);
The server didn't know rinfo.ip, so it spammed itself with the same message over and over again.

Related

Can't decode handshake request from client

I'm trying to connect a python3 socket with a JavaScript WebSocket. I'm testing the server code on localhost:8080, and connecting with Chrome(94.0).
The WebSocket client and the socket server do establish a connection. However, the connection would be shut down if the server did not follow the protocol and respond to the handshake. According to the protocol, the client WebSocket sends a utf-8 encoded GET request to the socket server, and the server must parse that request in order to complete the handshake.
What I get from the client is this:
\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03\x97t\xb1\xf7\xac\x99\x91\xd4\xf5\n\xdf\xc3X\x8af<\xbe\x99(0\x88\x9a!\xc6\xc9\x17]\xfe\xd9sP\xcc \xa8\xcf\x90{\x8a\xfcm\xbcj-5\xdf\xf90\x81\xc8Y\xc1\x85q"\xfe!C\xbb\t\xbd}\xe0\x8d\xf1\xe5\x00 \x1a\x1a\x13\x01\x13\x02\x13\x03\xc0+\xc0/\xc0,\xc00\xcc\xa9\xcc\xa8\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93\x1a\x1a\x00\x00\x00\x17\x00\x00\xff\x01\x00\x01\x00\x00\n\x00\n\x00\x08\xfa\xfa\x00\x1d\x00\x17\x00\x18\x00\x0b\x00\x02\x01\x00\x00#\x00\x00\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\r\x00\x12\x00\x10\x04\x03\x08\x04\x04\x01\x05\x03\x08\x05\x05\x01\x08\x06\x06\x01\x00\x12\x00\x00\x003\x00+\x00)\xfa\xfa\x00\x01\x00\x00\x1d\x00 \xfa)\xd5\x85<\x81.\x7f\xc0\x87wA!\xf1\xc9\xf80\xeb\x01\xdc\xed3m\xd1\x98\xd6\xd8\xd7\x7f#\rM\x00-\x00\x02\x01\x01\x00+\x00\x0b\n\x8a\x8a\x03\x04\x03\x03\x03\x02\x03\x01\x00\x1b\x00\x03\x02\x00\x02JJ\x00\x01\x00\x00\x15\x00\xf7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
The client consistently sends these bytes, although it this does not look like a legitimate GET request. This can't be decoded by utf-8 or by other encodings including utf-16-le, utf-16-be, unicode-escape, etc.
client source:
var client = new WebSocket('wss://127.0.0.1:8080')
client.onopen = function(e) {
console.log("open");
}
client.onmessage = function(e) {
console.log(e.data)
}
server handshake handler:
def handshake(client, address):
req = client.recv(1024).decode('utf-8')
key = (re.search('Sec-WebSocket-Key:\s+(.*?)[\n\r]+', req).groups()[0].strip())
response_key = b64encode(sha1(key + sockey).digest())
response = '\r\n'.join(websock_ans).format(key=response_key)
client.send(response.encode('utf-8'))
As the client request isn't utf-8 bytes, this gives a decoding error in line 2.
following the websocket protocol (https://datatracker.ietf.org/doc/html/rfc6455), sockey and websock_ans are defined as follows:
sockey = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
websock_ans = {
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key}\r\n\r\n',
}
Does WebSocket compress/encrypt its GET requests? As far as I checked, the documents do not state any compression/encryption algorithms.
Thanks in advance.
Use gzip to convert the bytes into objects.

How to send udp packages using nodejs?

Well, I have a small route that should send an UDP package and print a confirmation. According to the documentation on the node, the following should work fine:
const dgram = require('dgram');
export async function sendUDP(sess, parameters: {}, res) {
const client = dgram.createSocket('udp4');
client.send('Hello World!',0, 12, 12000, '127.0.0.1', function(err, bytes) {
client.close();
});
//res is the response object from express
return res.send("Send udp packet");
}
It should send an UDP request to port 12000 on the callback IP (local machine). And also send a reply that the UDP packet has been sent.
I notice the reply Send udp packet received at postman when I post to the correct URL. So that is working.
However, the UDP packages seem to be lost, using tcpdump on my local ubuntu results in nothingness:
sudo tcpdump -n udp port 12000
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp5s0, link-type EN10MB (Ethernet), capture size 262144 bytes
0 packets captured
0 packets received by filter
0 packets dropped by kernel
(While tcpdump has been kept running during the test of the functions of course). Where do the UDP requests go? What happened?
I wish to have a life logger so that I can test nodejs applications using udp easily.
You need to tell tcpdump the interface it needs to listen.
tcpdump -i lo udp port 12000
lo is the interface for localhost.
More information in this link
You can use wireshark if you want to save the traffic log.
I use '!(udp.port == 53 || tcp.port == 53) && udp' as a filter to look only to udp packet.
I add this code to my server and send the udp packet there to print the content
const dgram = require('dgram');
const serverUDP = dgram.createSocket('udp4');
serverUDP.on('error', (err) => {
console.log(`serverUDP error:\n${err.stack}`);
serverUDP.close();
});
serverUDP.on('message', (msg, rinfo) => {
console.log(`serverUDP got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
serverUDP.on('listening', () => {
const address = serverUDP.address();
console.log(`serverUDP listening ${address.address}:${address.port}`);
});
serverUDP.bind(3001);
It is the code sample from the node documentation

Connection to socket gets error "WebSocket opening handshake timed out" using Javascript and C#

About 4 hours of research...here we go.
I have a C# program that sends and listens for anything coming in a specific Socket. Using the sockets, C# can send stuff to it and can receive from it just fine. Now, going to my JavaScript file, I'm using the WebSocket interface to communicate with C#, but doesn't work (usually times out after a couple of minutes). When the Socket is online, the JavaScript code will take up to about 4 minutes then throw an error saying "WebSocket opening handshake timed out". The thing is I know that it can find because, when the port of the ip doesn't exist the JavaScript file throws an error in the next couple seconds.
Things I've done:
Turn off all firewalls, use both ws and wss at the beginning of the ip and port (ex: wss://xxx.xxx.x.xx:11111), change the port, change the ip to a valid ip still reachable, research for 4 hours.
C#:
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = IPAddress.Parse("ip");
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
Socket listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
Console.WriteLine("Waiting connection...");
Socket clientSocket = listener.Accept();
byte[] bytes = new Byte[1024];
string data = null;
while (true)
{
int numByte = clientSocket.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, numByte);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Text received -> {0} ", data);
byte[] message = Encoding.ASCII.GetBytes("Test Server");
clientSocket.Send(message);
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
JavaScript:
socket = new WebSocket("wss://ip:11111");
socket.onopen = function()
{
alert("Connected!");
}
socket.onerror = function()
{
alert("Connection Failed");
}
The ip is local
Long story short, C# can communicate with itself and JavaScript can find it but can't communicate with it.
Properly complete a handshake. (Or use a library / connection type that does.)
The WebSocket protocol (as original defined in RFC6455 - The WebSocket Protocol) does not open a plain unrestricted socket, in part for security reasons.
Since the handshake is not complete, the client WS request will timeout as the HTTP “Upgrade” response is never received. Until the handshake is complete, the WS will not be active over the underlying TCP connection.
Initiating a WebSocket connection (“the handshake”) is defined in section 4 of the RFC. It is also discussed in How JavaScript works: Deep dive into WebSockets and HTTP/2 with SSE + how to pick the right path.
The client establishes a WebSocket connection through a process known as the WebSocket handshake. This process starts with the client sending a regular HTTP request to the server. An Upgrade header is included in this request which informs the server that the client wishes to establish a WebSocket connection.
..
Now that [after] the handshake is complete the initial HTTP connection is replaced by a WebSocket connection that uses the same underlying TCP/IP connection. At this point, either party can start sending data.

TCP server in Webassembly (C++) fails with accept()

I wrote a simple TCP server-client native application in C. It works as expected (Linux Fedora as well as Cygwin for Windows 10). When I compiled it using EM++ (or EMCC), it built the JS & WASM fine.
$ em++ TcpService.cpp -o TcpService.js -s ASYNCIFY=1
However, while running the server, I see the following error; though it is stuck waiting for arrival of client-data, it never really connects:
$ node TcpService.js
Waiting for arrival of messages ...
TypeError: Cannot read property 'stream' of undefined
TypeError: Cannot read property 'stream' of undefined
...
I narrowed down the problem to the accept(3) call. Note that previously, I would see a stacktrace (not very useful), in addition to the above TypeError. Now that I am compiling the code with "-s ASYNCIFY=1", the stack trace is gone. However, the client program still doesn't connect (neither native build nor its WASM).
The server program uses simple BSD sockets:
void server(void)
{
// port to start the server on
int SERVER_PORT = 8877;
// socket address used for the server
struct sockaddr_in _ServerAddr;
memset(&_ServerAddr, 0, sizeof(_ServerAddr));
_ServerAddr.sin_family = AF_INET;
// htons: host to network short: transforms a value in host byte
// ordering format to a short value in network byte ordering format
_ServerAddr.sin_port = htons(SERVER_PORT);
// htonl: host to network long: same as htons but to long
_ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// create a TCP socket, creation returns -1 on failure
int listen_sock;
if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
throw std::runtime_error("could not create listen socket\n");
}
// bind it to listen to the incoming connections on the created server
// address, will return -1 on error
if ((bind(listen_sock, (struct sockaddr *)&_ServerAddr,
sizeof(_ServerAddr))) < 0) {
throw std::runtime_error("could not bind socket\n");
}
int wait_size = 16; // maximum number of waiting clients, after which
// dropping begins
if (listen(listen_sock, wait_size) < 0) {
throw std::runtime_error("could not open socket for listening\n");
}
// socket address used to store client address
struct sockaddr_in client_address;
int client_address_len = 0;
// run indefinitely
while (true) {
// open a new socket to transmit data per connection
int sock;
printf("Waiting for arrival of messages ...\n");
if ((sock =
accept(listen_sock, (struct sockaddr *)&client_address,
(socklen_t *)&client_address_len)) < 0) {
throw std::runtime_error("could not open a socket to accept data\n");
}
int n = 0;
int len = 0, maxlen = 100;
char buffer[maxlen];
char *pbuffer = buffer;
printf("client connected with ip address: %s\n",
inet_ntoa(client_address.sin_addr));
// keep running as long as the client keeps the connection open
while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {
pbuffer += n;
maxlen -= n;
len += n;
printf("received: '%s'\n", buffer);
// echo received content back
send(sock, buffer, len, 0);
}
close(sock);
}
close(listen_sock);
}
The client is equally simple:
void sendMessage(void)
{
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
inet_pton(AF_INET, server_name, &server_address.sin_addr);
server_address.sin_port = htons(server_port);
if ((_Sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("could not create socket\n");
}
if (connect(_Sock, (struct sockaddr*)&server_address,
sizeof(server_address)) < 0) {
printf("could not connect to server\n");
return;
}
const char* data_to_send = "test message";
send(_Sock, data_to_send, strlen(data_to_send), 0);
}
Googling for the error "TypeError: Cannot read property 'stream' of undefined" did NOT prove very useful, especially WRT the stream property - most pages are only relevant to AWS, whereas mine is a simple, local test-program.
I also installed the required websockets NPMs before I could get node to run the application.
If you have existing TCP networking code written in C/C++ that utilizes the Posix Sockets API, by default Emscripten attempts to emulate such connections to take place over the WebSocket protocol instead. For this to work, you will need to use something like WebSockify on the server side to enable the TCP server stack to receive incoming WebSocket connections. This emulation is not very complete at the moment, it is likely that you will run into problems out of the box and need to adapt the code to work within the limitations that this emulation provides.
This is the default build mode for POSIX sockets, no linker flags or option settings are needed to enable it.
Full POSIX Sockets over WebSocket Proxy Server
Emscripten provides a native POSIX Sockets proxy server program, located in directory tools/websocket_to_posix_proxy/, that allows full POSIX Sockets API access from a web browser. This support works by proxying all POSIX Sockets API calls from the browser to the Emscripten POSIX Sockets proxy server (via transparent use of WebSockets API), and the proxy server then performs the native TCP/UDP calls on behalf of the page. This allows a web browser page to run full TCP & UDP connections, act as a server to accept incoming connections, and perform host name lookups and reverse lookups. Because all API calls are individually proxied, this support can be slow. This support is mostly useful for developing testing infrastructure and debugging.
The following POSIX sockets functions are proxied in this manner:
socket(), socketpair(), shutdown(), bind(), connect(), listen(), accept(), getsockname(), getpeername(), send(), recv(), sendto(), recvfrom(), sendmsg(), recvmsg(), getsockopt(), setsockopt(), getaddrinfo(), `getnameinfo().
The following POSIX sockets functions are currently not proxied (and will not work):
poll(), close() (use shutdown() instead), select()
To use POSIX sockets proxying, link the application with flags “-lwebsocket.js -s PROXY_POSIX_SOCKETS=1 -s USE_PTHREADS=1 -s PROXY_TO_PTHREAD=1”. That is, POSIX sockets proxying builds on top of the Emscripten WebSockets library, and requires multithreading and proxying the application main() to a pthread.
For an example of how the POSIX Sockets proxy server works in an Emscripten client program, see the file tests/websocket/tcp_echo_client.cpp.
https://emscripten.org/docs/porting/networking.html

Unable to connect to Mosquitto over Websocket

I am unable to connect to my local Mosquitto 1.4.10 broker from a JavaScript client over a Websocket.
The same JavaScript client is successfully connecting to the public broker at test.mosquitto.org on port 8080 over a Websocket.
The MQTT protocol connection on port 1883 is working fine, which I tested using mosquitto_pub and mosquitto_sub.
My broker is set up within a VirtualBox running Ubuntu 14.04.
I have libwebsockets installed on the same virtual machine.
My local broker was compiled with WITH_WEBSOCKETS:=yes in the config.mk file
I am loading the JavaScript client web page from the same virtual machine from a Firefox browser and seeing the following error message in the browser console:
Firefox can't establish a connection to the server at
ws://localhost:8080/mqtt
Your suggestions on fixing this will be greatly appreciated.
Thanks.
Here is my Mosquitto .conf file:
port 1883
listener 8080
protocol websockets
log_type all
websockets_log_level 1023
connection_messages true
Here is the Mosquitto server's log (with websockets logging level set to 1023, and verbose logging turned on - no messages appear when I load the JavaScript web page):
1481381105: mosquitto version 1.4.10 (build date 2016-12-10
18:47:37+0530) starting
1481381105: Config loaded from /etc/mosquitto/mosquitto.conf.
1481381105: Opening websockets listen socket on port 8080.
1481381105: Initial logging level 1023
1481381105: Libwebsockets version: 2.1.0 manavkumarm#manav-alljoyn
1481381105: IPV6 not compiled in
1481381105: libev support not compiled in
1481381105: libuv support not compiled in
1481381105: Threads: 1 each 1024 fds
1481381105: mem: platform fd map: 4096 bytes
1481381105: Compiled with OpenSSL support
1481381105: Creating Vhost 'default' port 8080, 3 protocols, IPv6 off
1481381105: Using non-SSL mode
1481381105: Listening on port 8080
1481381105: mem: per-conn: 376 bytes + protocol rx buf
1481381105: canonical_hostname = mqtt
1481381105: Opening ipv4 listen socket on port 1883.
1481381105: Opening ipv6 listen socket on port 1883.
Here is the JavaScript source code:
<html>
<body>
<script src="mqttws31.js"></script>
<script>
try
{
// Create a client instance
console.log("Creating client object...");
client = new Paho.MQTT.Client("localhost", Number(8080), "manav");
//client = new Paho.MQTT.Client("test.mosquitto.org", Number(8080), "manav");
// set callback handlers
console.log("Setting handlers...");
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
console.log("Connecting...");
client.connect( {
onSuccess: onConnect,
mqttVersion: 4
});
}
catch (e)
{
console.log("Error: " + e.description);
}
// called when the client connects
function onConnect()
{
// Once a connection has been made, make a subscription and send a message.
console.log("Connected");
setTimeout( function() {
client.subscribe("world");
message = new Paho.MQTT.Message("Hello");
message.destinationName = "world";
client.send(message);
//client.disconnect();
}, 5000);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("Connection lost: " + responseObject.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.log("Received Message: " + message.payloadString);
client.disconnect();
}
</script>
<h1>My MQTT Websockets Example</h1>
</body>
</html>
I see I am little bit late on answer.
MQTT's port for websocket is 1884 or something else, you have 8080. Maybe thats the problem.
Isnt 8080 a reserved TCP port?
Also, I know you have javascript code, but its paho. I was able to make publisher(it uses same class like subscriber so it must be on subscriber side too - this is just assumption though) work on websockets with paho python client which must be initialized with defining transport parameter. -> communicating with browser(see below for javascript)
mqtt.Client(transport='websockets')
Leaving that parameter MQTT assumes using TCP
mqtt.Client()
Also:
Config on my broker:
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
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
listener 1883
listener 1884
protocol websockets
I found my very old Javascript with paho-mqtt. It was working, so I just put it here.
Its subscriber and publisher at the same time. Together with the config, It was working like charm.
class sub{
constructor(hostname,port,clientid,topic){
this.buffer = []
this.hostname=hostname;
this.port=port;
this.clientid = clientid;
this.topic = topic;
this.client = new Paho.MQTT.Client(hostname,port, clientid);
// set callback handlers
this.client.onConnectionLost = this.onConnectionLost;
this.client.onMessageArrived = this.onMessageArrived.bind(this);
// connect the client
this.client.connect({onSuccess:this.onConnect});
}
onConnect(){
console.log('OnConnect');
}
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
this.buffer.push(JSON.parse(message.payloadString));
}
subsribe(){
this.client.subscribe(this.topic)
}
publish(message){
console.log(message)
var mg = new Paho.MQTT.Message(JSON.stringify(message));
mg.destinationName = this.topic;
this.client.send(mg);
}
}
var x
x = new sub('xx.xx.xx.xx',1884,'clientID','LED');
function on(){
x.publish({'LED':'ON'});
}
function off(){
x.publish({'LED':'OFF'});
}

Categories

Resources