MQTT Js Last Will Message not getting published - javascript

I have the below code -->
var last_will = new Paho.MQTT.Message("last message");
last_will.destinationName = "Bridge123";
client = new Paho.MQTT.Client("broker.mqttdashboard.com", Number("8000"), "AX123");
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
client.connect({onSuccess:onConnect} , {willMessage:last_will});
When i disconnect the client i expect a last will message being sent to the topic i have created .. Am using Paho 's mqtt version -3.1 .. Websockets are getting created fine but i do not see the last will message ...
Can anyone guide here ?
Adding the bigger picture :
I have a Python script p gathering current on / off status of a IOT device in the local environment and publishing to a topic "IOT1" over mqtt . I do not want the python script always running to get status from the IOT device as it overloads the device .. To solve this i am in need of finding active clients for "IOT1" topic so that i run or pause the thread sending requests to the IOT device in the local environment .. Is there a way other than the last will message to know this ?

Last Will and Testament messages are only published if client does not disconnect cleanly.
If you close the connection gracefully it will not be sent.
Only when the server fails to receive a message or ping packet in the time out period will the server send the message.

willMessage should be the property of the first object. See below code snippet.
client.connect({onSuccess:onConnect, willMessage:last_will});

Related

How to receive data in real time from TCP socket using PHP or JS? [duplicate]

I have a vb.net application that opens a socket and listens on it.
I need to communicate via this socket to that application using a javascript running on a browser. That is i need to send some data on this socket so that the app which is listening on this socket can take that data, do some stuff using some remote calls and get some more data and put it back on the socket that my javascript needs to read and print it in the browser.
Ive tried, socket.io, websockify but none have proved to be useful.
Hence the question, is what i am trying even possible? Is there a way that a javascript running in a browser can connect to a tcp socket and send some data and listen on it for some more data response on the socket and print it to the browser.
If this is possible can some one point me in the right direction as to which would help me establish the goal.
As for your problem, currently you will have to depend on XHR or websockets for this.
Currently no popular browser has implemented any such raw sockets api for javascript that lets you create and access raw sockets, but a draft for the implementation of raw sockets api in JavaScript is under-way. Have a look at these links:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket
Chrome now has support for raw TCP and UDP sockets in its ‘experimental’ APIs. These features are only available for chrome apps and, although documented, are hidden for the moment. Having said that, some developers are already creating interesting projects using it, such as this IRC client.
To access this API, you’ll need to enable the experimental flag in your extension’s manifest. Using sockets is pretty straightforward, for example:
chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");
});
});
This will be possible via the navigator interface as shown below:
navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
() => {
// Permission was granted
// Create a new TCP client socket and connect to remote host
var mySocket = new TCPSocket("127.0.0.1", 6789);
// Send data to server
mySocket.writeable.write("Hello World").then(
() => {
// Data sent sucessfully, wait for response
console.log("Data has been sent to server");
mySocket.readable.getReader().read().then(
({ value, done }) => {
if (!done) {
// Response received, log it:
console.log("Data received from server:" + value);
}
// Close the TCP connection
mySocket.close();
}
);
},
e => console.error("Sending error: ", e)
);
}
);
More details are outlined in the w3.org tcp-udp-sockets documentation.
http://raw-sockets.sysapps.org/#interface-tcpsocket
https://www.w3.org/TR/tcp-udp-sockets/
Another alternative is to use Chrome Sockets
Creating connections
chrome.sockets.tcp.create({}, function(createInfo) {
chrome.sockets.tcp.connect(createInfo.socketId,
IP, PORT, onConnectedCallback);
});
Sending data
chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);
Receiving data
chrome.sockets.tcp.onReceive.addListener(function(info) {
if (info.socketId != socketId)
return;
// info.data is an arrayBuffer.
});
You can use also attempt to use HTML5 Web Sockets (Although this is not direct TCP communication):
var connection = new WebSocket('ws://IPAddress:Port');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
http://www.html5rocks.com/en/tutorials/websockets/basics/
Your server must also be listening with a WebSocket server such as pywebsocket, alternatively you can write your own as outlined at Mozilla
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
code sample:
var socket = new WS2S("wss://ws2s.feling.io/").newSocket()
socket.onReady = () => {
socket.connect("feling.io", 80)
socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}
socket.onRecv = (data) => {
console.log('onRecv', data)
}
See jsocket. Haven't used it myself. Been more than 3 years since last update (as of 26/6/2014).
* Uses flash :(
From the documentation:
<script type='text/javascript'>
// Host we are connecting to
var host = 'localhost';
// Port we are connecting on
var port = 3000;
var socket = new jSocket();
// When the socket is added the to document
socket.onReady = function(){
socket.connect(host, port);
}
// Connection attempt finished
socket.onConnect = function(success, msg){
if(success){
// Send something to the socket
socket.write('Hello world');
}else{
alert('Connection to the server could not be estabilished: ' + msg);
}
}
socket.onData = function(data){
alert('Received from socket: '+data);
}
// Setup our socket in the div with the id="socket"
socket.setup('mySocket');
</script>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
Bridge app that sits on the client's machine and can deal with both TCP/IP sockets and WebSockets. It will interact with the TCP/IP socket in question.
Server-side app (such as a JSP/Servlet WAR) that can talk WebSockets. It includes at least one HTML page (including server-side processing code if need be) to be accessed by a browser.
It should work like this
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
Repeat until either client disconnects/unloads
Note 1: The above steps are a vast simplification and do not include information about error handling and keepAlive requests, in the event that either client disconnects prematurely or the server needs to inform clients that it is shutting down/restarting.
Note 2: Depending on your needs, it might be possible to merge these components into one if the TCP/IP socket server in question (to which the bridge talks) is on the same machine as the server app.
The solution you are really looking for is web sockets. However, the chromium project has developed some new technologies that are direct TCP connections TCP chromium

How to detect client disconnect from redis in nodejs?

I am using the library node_redis as the client for a micro-service message client that I am writing. Clients get messages from their application in their outbox that they need to send to other services. Everything is working great but I am trying to build some resilience on the part of the application that uses the redis client to communicate with the redis-server.
My idea is that the redis client-server connection status should be highly available to the clients. I mean that if a connection goes down, I would like to know within the second instead of the default timeout of 300 seconds. Currently I am using the free redislabs tier hosted on AWS, but I should be moving this to run in its own container on my kubernetes cluster.
I need to know the state of client connections in the network because I would like to not send messages when the network conditions are not right and not rely on the error handling to handle this sort of event. Knowing how often and when these high latency events occur will also help me diagnose and improve my network and my microservices.
Note: I wanted to set the connect_timeout value in the client options but this is listed as deprecated.
Something like that?
var redis = require('redis');
var client = redis.createClient();
var reconnectAfter = 15000;
client.on( 'error', function () {
console.log( (new Date()) + " Redis: disconnect");
setTimeout( connect, reconnectAfter);
});
connect = function(){
client = redis.createClient();
}

Node.js/Socket.io: Create a bot who's always in chat lobby/room, detecting specific activity and reporting to server?

I am running Node.js and Socket.io on Linux Server.
I've created an online chat room/lobby, I am wondering how can I create like a daemon who has a role of user, he is connected to lobby always and is monitoring lobby, and messages that users post. When specific criteria is matched - report back to server.
For example, some user posts too many messages per minute, the bot would send message to user saying to slow down, if user continues bot would send request to server saying to kick that user.
I am new to node.js and socket.io, so I am not sure how to implement it.
I don't want to hard code every rule or criteria into server itself.
I don't think your way will be working. The way on top of my head is doing it on server. Socket.io can fire any event on client side and send to server, so you can ask server to listen to certain event and handle your logics accordingly on server. Below is some sample code for your reference.
client side:
this event will fire whenever client sends a message.
$("#msgbutton").click(function(){
socket.emit("message","some message client send");
});
server side:
socket.on('message', function(msg){
var now = new Date();
var lastsent = socket.lastsent; //socket is an object and you can store lastsent datetime to it
var diff = now.getTime() - socket.lastsent.getTime();
if (diff/1000 > 2) // if message interval is larger than 2 seconds
{socket.to(room).emit('message',msg); // send message to whole room}
else if
{ // maybe send a warning event to user }
});
The code is not tested, and only consider the time difference between current msg and last message. If you want to monitor the message sent event over certain time course, you will have to write your logics on server to do that. Hope this can give you some pointers.

Node JS + Socket.io application stops to receive events after some time

I am working on a Node JS + socket.io application.
The entire application works fine, but after about 5 mins the server stops to receive the events that the client triggers. :(
When the events are not triggered, I can see that the server is successfully receiving the heart beat.
debug - got heartbeat packet
debug - cleared heartbeat timeout for client 4cKMC4Iqje-7dDfibJZm
debug - set heartbeat interval for client 4cKMC4Iqje-7dDfibJZm
debug - emitting heartbeat for client 4cKMC4Iqje-7dDfibJZm
debug - websocket writing 2::
debug - set heartbeat timeout for client 4cKMC4Iqje-7dDfibJZm
I am also sure that the client is emitting the messages because, I can see the data being sent in the chrome Developer tools.
Following is the sample data that is being sent
5:::{"name":"ev_SendChatMessage","args":[{"chatMsg":"dgdfsgfs","aID":"10010001835364"}]}
Also, I have checked the results of TCP Dump at the server machine, it is successfully receiving the data packets.
Node version is v0.10.21
socket.io version is 0.9.16
Client Code
var socket;
$(function()
{
// Connect to the Live Proctoring Server.
socket = io.connect('http://autoproc.am.in:8899');
});
function SendChatMsg()
{
// This get called on click of a button
socket.emit( "ev_SendChatMessage", { chatMsg : "textToSend", aID : "123" } );
}
Server Code
var options = {};
var io = require( 'socket.io' ).listen( 8899, options );
// Called when a connection is made with a new Client
function OnConnection ( socket )
{
console.log( "Connection has been made with " + socket.id );
socket.on('ev_SendChatMessage', SendChatMessageFromModerator );
socket.on('disconnect', OnDisconnect );
}
// This stops getting called after some time. In the beginning it is getting called successfully.
function SendChatMessageFromModerator( data )
{
console.log( data );
}
Edit: To be more precise this thing happens only after around receiving 7-8 messages and emitting 7-8 messages.
Edit: I tried to change the transport mechanism from Web Socket to "xhr-polling". Even then I am facing same problem, instead that I can see something worth in the debug.
debug - xhr-polling received data packet 5:::{"name":"ev_SendChatMessage","args":[{"chatMsg":"sfsdfdsfs","aID":"10010001167896"}]}
debug - clearing poll timeout
debug - xhr-polling writing 8::
debug - set close timeout for client JfaWyiP3YqTRmqyzz4z6
debug - xhr-polling closed due to exceeded duration
debug - setting request GET /socket.io/1/xhr-polling/JfaWyiP3YqTRmqyzz4z6?t=1389965419417
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client JfaWyiP3YqTRmqyzz4z6
This clearly shows that data has reached the Node JS application.
I found the solution to my problem..
Problem was that I was creating a database connection pool, but I was not releasing the connections using dbConn.release();
Once the connections in the pool were exhausted the application kept on waiting for the database connection to be fetched from the pool.
In short, Devil was in the details. The details I had not mention in my question. hahaha..!!

Connecting to TCP Socket from browser using javascript

I have a vb.net application that opens a socket and listens on it.
I need to communicate via this socket to that application using a javascript running on a browser. That is i need to send some data on this socket so that the app which is listening on this socket can take that data, do some stuff using some remote calls and get some more data and put it back on the socket that my javascript needs to read and print it in the browser.
Ive tried, socket.io, websockify but none have proved to be useful.
Hence the question, is what i am trying even possible? Is there a way that a javascript running in a browser can connect to a tcp socket and send some data and listen on it for some more data response on the socket and print it to the browser.
If this is possible can some one point me in the right direction as to which would help me establish the goal.
As for your problem, currently you will have to depend on XHR or websockets for this.
Currently no popular browser has implemented any such raw sockets api for javascript that lets you create and access raw sockets, but a draft for the implementation of raw sockets api in JavaScript is under-way. Have a look at these links:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket
Chrome now has support for raw TCP and UDP sockets in its ‘experimental’ APIs. These features are only available for chrome apps and, although documented, are hidden for the moment. Having said that, some developers are already creating interesting projects using it, such as this IRC client.
To access this API, you’ll need to enable the experimental flag in your extension’s manifest. Using sockets is pretty straightforward, for example:
chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");
});
});
This will be possible via the navigator interface as shown below:
navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
() => {
// Permission was granted
// Create a new TCP client socket and connect to remote host
var mySocket = new TCPSocket("127.0.0.1", 6789);
// Send data to server
mySocket.writeable.write("Hello World").then(
() => {
// Data sent sucessfully, wait for response
console.log("Data has been sent to server");
mySocket.readable.getReader().read().then(
({ value, done }) => {
if (!done) {
// Response received, log it:
console.log("Data received from server:" + value);
}
// Close the TCP connection
mySocket.close();
}
);
},
e => console.error("Sending error: ", e)
);
}
);
More details are outlined in the w3.org tcp-udp-sockets documentation.
http://raw-sockets.sysapps.org/#interface-tcpsocket
https://www.w3.org/TR/tcp-udp-sockets/
Another alternative is to use Chrome Sockets
Creating connections
chrome.sockets.tcp.create({}, function(createInfo) {
chrome.sockets.tcp.connect(createInfo.socketId,
IP, PORT, onConnectedCallback);
});
Sending data
chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);
Receiving data
chrome.sockets.tcp.onReceive.addListener(function(info) {
if (info.socketId != socketId)
return;
// info.data is an arrayBuffer.
});
You can use also attempt to use HTML5 Web Sockets (Although this is not direct TCP communication):
var connection = new WebSocket('ws://IPAddress:Port');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
http://www.html5rocks.com/en/tutorials/websockets/basics/
Your server must also be listening with a WebSocket server such as pywebsocket, alternatively you can write your own as outlined at Mozilla
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
code sample:
var socket = new WS2S("wss://ws2s.feling.io/").newSocket()
socket.onReady = () => {
socket.connect("feling.io", 80)
socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}
socket.onRecv = (data) => {
console.log('onRecv', data)
}
See jsocket. Haven't used it myself. Been more than 3 years since last update (as of 26/6/2014).
* Uses flash :(
From the documentation:
<script type='text/javascript'>
// Host we are connecting to
var host = 'localhost';
// Port we are connecting on
var port = 3000;
var socket = new jSocket();
// When the socket is added the to document
socket.onReady = function(){
socket.connect(host, port);
}
// Connection attempt finished
socket.onConnect = function(success, msg){
if(success){
// Send something to the socket
socket.write('Hello world');
}else{
alert('Connection to the server could not be estabilished: ' + msg);
}
}
socket.onData = function(data){
alert('Received from socket: '+data);
}
// Setup our socket in the div with the id="socket"
socket.setup('mySocket');
</script>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
Bridge app that sits on the client's machine and can deal with both TCP/IP sockets and WebSockets. It will interact with the TCP/IP socket in question.
Server-side app (such as a JSP/Servlet WAR) that can talk WebSockets. It includes at least one HTML page (including server-side processing code if need be) to be accessed by a browser.
It should work like this
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
Repeat until either client disconnects/unloads
Note 1: The above steps are a vast simplification and do not include information about error handling and keepAlive requests, in the event that either client disconnects prematurely or the server needs to inform clients that it is shutting down/restarting.
Note 2: Depending on your needs, it might be possible to merge these components into one if the TCP/IP socket server in question (to which the bridge talks) is on the same machine as the server app.
The solution you are really looking for is web sockets. However, the chromium project has developed some new technologies that are direct TCP connections TCP chromium

Categories