WebSockets connection.send not function error - javascript

I have a Tornado client application which runs fine at its current state: In a simplified version, it has a structure like the folllowing code piece:
function comms(callback, newSession, connection) {
if (newSession == true) {
connection = new WebSocket('ws://localhost:9022/id/01234');
connection.onopen = function () {
alert("connected");
connection.send('hello world');
};
}
connection.onerror = function (error) {
alert('WebSocket Error ' + error);
};
connection.onmessage = function (e) {
alert('>> message from Host: ' + e.data);
callback(e.data, connection);
}
}
I can connect, I can detect connection is on, I can send messages. I can receive messages. I can forward message via callback function and come back. No problem. All these are done via:
connection.onXXX event handler functions.
Now I want to send some unsolicited messages to server like the following:
function comms(callback, newSession, connection, request=false) {
if (newSession == true) {
connection = new WebSocket('ws://localhost:9022/id/01234');
connection.onopen = function () {
alert("connected");
connection.send('hello world');
};
}
connection.onerror = function (error) {
alert('WebSocket Error ' + error);
};
connection.onmessage = function (e) {
alert('>> message from Host: ' + e.data);
callback(e.data, connection);
}
if (request == true) {
connection.send("request_msg");
}
}
Although connection is open, I can not send such a request message. I receive:
"connection.send is not a function" error.
As I understand, somehow send request must be wrapped into a function, like other connection.onXXXX event handlers. But I do not have any such event or handler.
How can I send my message?

It would seem you would need to do this within an event.
UPDATED:
The onmessage event is what is fired on the server side, so any client processing can't be done in that event handler. I would suggest the client side functionality should be handled in a different function (not comms).
According to this reference tutorial (an-introduction-to-websockets), just call the send request from within the function from the client that requests the message.
Ie. as per the tutorials example, found here, the request is called when the form is submitted / send message button is pressed. This is all wrapped in the onload function.
So you need some client side event or loop that can call the socket connection(socket).send() function, simply passing in text should be sufficient.
Does this help at all or does your application in it's 'complex' state achieve this already?

Related

Trying to write a wrapper class around Paho MQTT Javascript client

I'm trying to write a simple wrapper class around the Paho MQTT JavaScript client. (The idea is to put some extra validation around MQTT messaging, to ensure messages are processed in the correct order.)
I'm not very comfortable with JavaScript classes, and I'm getting in a mess trying to work out what's wrong with this...
class Hermes {
constructor(uri, topic, callback) {
var clientId = "clientID_" + parseInt(Math.random() * 1000);
this.client = new Paho.MQTT.Client(uri, clientId);
this.topic = topic;
this.callback = callback;
this.client.onMessageArrived = this._onMessageArrived;
this.client.onConnectionLost = this._onConnectionLost;
this.client.connect({
onSuccess: this._onConnect,
onFailure: this._onFailure
});
}
_onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("_onConnect: " + this.client.clientId)
this.client.subscribe(this.topic);
}
// called when connection fails
_onFailure(responseObject) {
console.log("_onFailure: "+responseObject.errorMessage);
}
// called when a message arrives
_onMessageArrived(message) {
console.log("_onMessageArrived: "+message.payloadString)
// TODO: validate message and pass to callback
}
// called when client loses connection
_onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost: "+responseObject.errorMessage);
}
}
}
function handleMessage(message) {
// TODO: handle message
}
var hermes = new Hermes("ws://mqtt.example.com:9001/mqtt", "test", handleMessage);
Expected result:
_onConnect: clientID_xxx should be logged in the console when the client successfully connects.
Actual result:
onConnectionLost: AMQJS0005E Internal error. Error Message: undefined is not an object (evaluating 'this.client.clientId'), Stack trace: _onConnect#file:///Users/richardguy/Desktop/hermes.js:16:45
The MQTT broker is running on a VPS and I can publish/subscribe messages successfully using the Paho Javascript library outside of a class, like so...
uri = "ws://mqtt.example.com:9001/mqtt"
var clientId = "clientID_" + parseInt(Math.random() * 1000);
client = new Paho.MQTT.Client(uri, clientId);
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
client.connect({
onSuccess: onConnect,
onFailure: onFailure
});
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("_onConnect: " + client.clientId)
client.subscribe("test");
}
// called when connection fails
function onFailure(responseObject) {
console.log("_onFailure: "+responseObject.errorMessage);
}
// called when a message arrives
function onMessageArrived(message) {
console.log("_onMessageArrived: "+message.payloadString)
// TODO: validate message and pass to callback
}
// called when client loses connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost: "+responseObject.errorMessage);
}
}
Is this just a mistake in the class definition, or something to do with the Paho MQTT library??
Solution:
I needed to pass an object (in this case the instance of the Hermes class) to use as the context for the onSuccess callback rather than using this (which isn't what I thought it was, as usual...), using invocationContext in the connection options.
class Hermes {
constructor(uri, topic, callback) {
var clientId = "clientID_" + parseInt(Math.random() * 1000);
this.client = new Paho.MQTT.Client(uri, clientId);
this.topic = topic;
this.callback = callback;
this.client.onMessageArrived = this._onMessageArrived;
this.client.onConnectionLost = this._onConnectionLost;
this.client.connect({
onSuccess: this._onConnect,
onFailure: this._onFailure,
invocationContext: this
});
}
_onConnect(responseObject) {
// Once a connection has been made, make a subscription and send a message.
let self = responseObject.invocationContext;
self.client.subscribe(self.topic);
}
// called when connection fails
_onFailure(responseObject) {
console.log("_onFailure: "+responseObject.errorMessage);
}
// called when a message arrives
_onMessageArrived(message) {
console.log("_onMessageArrived: "+message.payloadString)
// TODO: validate message and pass to callback
}
// called when client loses connection
_onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost: "+responseObject.errorMessage);
}
}
}
function handleMessage(message) {
}
var hermes = new Hermes("ws://mqtt.example.com:8080/mqtt", "test", handleMessage);
Your problem is that this is not what you think it is.
The callbacks are all made from the clients network handler, so this is actually a reference to the handler.
You can pass an object to use as the context for the onSuccess and onFailure callbacks in the connection options using invocationContext, but not for the other callbacks.

nodejs and mqtt sending message either once or constantly

I am using NodeJS with the express and mqtt packages.
Whenever the user pushes the button with the value 'test' a MQTT message should be sent.
However, whenever I send the mqtt message it is send either once when I use 'client.end()' or it keeps on sending the message constantly. I canĀ“t send it twice when I push the button again
I use following code:
module.exports =
{
Send
};
function Send(User){
client.on('connect', function() {
client.publish('alarm/reset', 'Hallo' + Test);
client.end();
});
}
In the '\' following code is used
router.post('/', Authencitation, function(req,res){
var test = req.body.test;
if (test == 'test')
{
reset.Send(req.session.user);
console.log('inside reset');
}
res.redirect('/');
});
However, I alway get inside the function inside reset whenever the button is clicked. It seems it is a mistake made in the function Send(User) but I cannot spot the error.
Following solution worked for me:
function Send(Test){
var mqtt = require('mqtt');
var client = mqtt.connect()
client.on('connect', function() {
client.publish('Test', 'Hallo' + username);
client.end();
});
}

SOCKJS client - Detect server is unreachable

I'm using vertxbus that internally built upon sockjs and I have a basic question.
When I call 'onopen' for the first time in order to establish a connection, How can I know that server is down?
At this point when I call 'onopen' and pass a callback function - if server is down the method is stuck and doesn't return at all.
Thanks!
You can check this code , where I'm using EventBus.
Here is the Reference code
this.eventBus = new EventBus(this.URL);
this.eventBus.onopen = (e) => {
this._opened = true;
console.log("open connection");
this.callHandlers('open', e);
this.eventBus.publish("http://localhost:8082", "USER LOGIN INFO");
this.eventBus.registerHandler("http://localhost:8081/pushNotification", function (error, message) {
console.log(message.body);
//$("<div title='Basic dialog'>Test message</div>").dialog();
});
}
this.eventBus.onclose = (e) => {
this.callHandlers('close', e);
}
}

Websocket second message doesn't send?

I have a websocket where I need to send two messages. It looks like the second message isn't being received. I'm not sure if this is a problem with my code or the websocket itself. I've used the Chrome Advanced Rest Tools Client and was able to send both messages successfully, but I'm not sure why it's not working in my code.
var ws = new WebSocket('ws://localhost:15449/');
ws.on('open', function open() {
console.log('i am open');
ws.send(JSON.stringify(data1));
//ws.send(JSON.stringify(data2));
ws.emit('sendData2');
});
ws.on('sendData2', function sendBar() {
console.log('testing!!');
ws.send(JSON.stringify(data2));
});
ws.on('message', function message(msg1, msg1) {
//the data received is a buffer
console.log('received:', msg1, msg1);
ws.close();
done();
});
Is there not a way to distinguish the different data that is being sent in ws.on('message')?
I figured it out. I needed to add an if check to make sure i got the first data and then send the second one.
var ws = new WebSocket('ws://localhost:15449/');
ws.on('open', function open() {
console.log('i am open');
ws.send(JSON.stringify(data1));
});
ws.on('message', function message(msg) {
if(...) {
ws.send(JSON.stringify(data2));
}
console.log('received:', msg);
ws.close();
done();
});

JavaScript callbacks function object

i try to learn node.js and try to create a new TCP Server connection. The code
var server = require('net').createServer(function(socket) {
console.log('new connection');
socket.setEncoding('utf8');
socket.write("Hello! You can start typing. Type 'quit' to exit.\n");
socket.on('data', function(data) {
console.log('got:', data.toString());
if (data.trim().toLowerCase() === 'quit') {
socket.write('Bye bye!');
return socket.end();
}
socket.write(data);
});
socket.on('end', function() {
console.log('Client connection ended');
});
}).listen(4001);
look at the callback function, after then, they call listen method. What is this for kind of object.
What it basically says is:
function myHandler(socket) {
// everything up to socket.on('end')
}
var server = require('net').createServer(myHandler);
server.listen(4001);
So it's just creating a socket server with a handler function, and then make the server listen to port 4001.

Categories