NodeJS getting response from net socket write - javascript

I'm trying to get a response from specific requests via the write function.
I'm connected to an equipment via the net module (which is the only way to communicate with it). Currently, I have an .on('data',function) to listen to responses from the said equipment. I can send commands via the write functions to which I am expecting to receive a line of response. How can I go about doing this?
Current code:
server = net.Socket();
// connect to server
server.connect(<port>,<ip>,()=>{
console.log("Connected to server!");
});
// log data coming from the server
server.on("data",(data)=>{
console.log(''+data);
});
// send command to server
exports.write = function(command){
server.write(command+"\r\n");
};
This is a working code. Sending a command to the equipment via server.write returns a response which right now only appears in Terminal. I'd like to return that response right after the write request. Preferably within the exports.write function.

Add a callback argument to your exports.write function can solve your problem.
exports.write = function(command, callback){
server.write(command+"\r\n");
server.on('data', function (data) {
//this data is a Buffer object
callback(null, data)
});
server.on('error', function (error) {
callback(error, null)
});
};
call your write function
var server = require('./serverFilePath')
server.write('callback works', function(error, data){
console.log('Received: ' + data)
})

Related

(javascript) Unable to return value received in Socket.on(event)

Basically I have a client side code that sends data to the server, the server responds with data which calls a socket.on(event) in the client side code. Within the function that is immediately run I can log the received data but I cannot return it to outside for the life of me.
function receive_data(){
socket.off('Sent_data_to_client').on('Sent_data_to_client',(player_info));
console.log(player_info)
}
If i try to log player_info it tells me it is undefined "Uncaught (in promise) ReferenceError: player_info is not defined". I want to return player_info as the result of the receive_data function but it is undefined.
I am new to javascript and Socket.Io as a whole, i apologise for any obvious mistakes made.
Sockets in JS doesnt work like this. Have a specifics events.
https://nodejs.org/api/net.html#new-netsocketoptions
This is the Node JS documentation, but it doesn't matter because Node JS is based on "V8 engine", that is, it's the same.
As you can see in the documentation it indicates that there are a series of events that the socket can handle, among them the 'data', calling a callback function where you implement the necessary logic for your code.
In this case, for example:
const net = require('net');
const socket = new net.Socket();
// Open a socket connection with example.com
socket.connect(80, 'example.com', () => {
console.log('Connected');
});
socket.on('data', (data) => {
console.log(`Recived: ${data}`);
});
socket.on('error', (error) => {
console.log(`Error: ${error}`);
});
You should change the function definition to accept an argument, which will be the data that the server sends.
function receive_data(){
socket.off('Sent_data_to_client').on('Sent_data_to_client', function(player_info) {
console.log(player_info);
return player_info;
});
}

Dialogflow Webhook (Webhook call failed. Error: 500 Internal Server Error)

I've followed this tutorial's code (https://dialogflow.com/docs/getting-started/basic-fulfillment-conversation) to return results of an API to dialog flow. However my webhook keeps failing. Can someone help me figure out why?
Here's one of the failed conversations:
Here's my code:
'use strict';
const http = require('http');
exports.Hadoop = (req, res) => {
// Get name node server from the request
let nameNodeServer = req.body.queryResult.parameters['nameNodeServer']; // nameNodeServer is a required param
// Call the Hadoop API
getNameNodeInfo(nameNodeServer).then(function(output) {
res.json({ 'fulfillmentText': output }); // Return the results to Dialogflow
}).catch(() => {
res.json({ 'fulfillmentText': 'getNameNodeInfo() Error'- });
});
};
function getNameNodeInfo (nameNodeServer) {
return new Promise((resolve, reject) => {
// Create url for the HTTP request to get the name node info
let url = 'http://' + nameNodeServer + '[rest of url]';
// Make the HTTP request to get the name node info
http.get(url, (res) => {
let body = ''; // var to store the response chunks
res.on('data', (chunk) => {body += chunk; });
res.on('end', () => {
// After all the data has been received, parse the JSON for desired data
let response = JSON.parse(body);
let beans = response['beans'][0];
// Create response
let output = `Percent Used: ${beans['PercentUsed']}`;
// Resolve the promise with the output text
console.log(output);
resolve(output);
});
res.on('error', (error) => {
console.log(`Error calling the Hadoop API: ${error}`);
reject();
});
});
});
}
I believe the getNameNodeInfo function and the retrieval of the name node server are correct, as they logged the correct output in debugging.
Diagnostic Info:
I contacted someone at Dialogflow and this was their response.
Thank you for providing all the information. I have observed in your
code that you have used http requests instead of https. The service
must use HTTPS and the URL must be publicly accessible in order for
the fulfillment to function. Dialogflow does not support self-signed
SSL certs. For information on SSL setup, please refer to this :
https://developers.google.com/web/fundamentals/security/encrypt-in-transit/enable-https
We've had a somewhat different, but related, issue:
Internal Server Error when running an agent.
“status”: {
“code”: 500,
“errorType”: “internal_server_error”,
“errorDetails”: “Internal Server Error”
},
This error was not caused by any changes we introduced. We are using that agent in a dev version of an app and one morning it stopped working.
We tested by creating a .zip and restoring into a new agent. The new agent would work properly, but we would continue to get the 500 error on the agent hooked into our dev app. We submitted a help request and overnight the error got resolved. We suspect that DialogFlow team had to manually reboot the server or something similar.

Cannot Send Function In Object Javascript Using Socket IO

This Is my code client socket.io, im trying to emit data and callback to server
_this.emitHandler = function(event, data, callback){
var packet = {};
if(data){
packet.data = data;
}
if(callback){
packet.callback = callback;
}
io.emit(event, packet); // emit packet to server with data and callback
}
and when i console.log my packet its just print data, the callback disappeared. this is my server code
io.on('*', function(socket, args, next){
console.log(args) // this args just print data in console
}
im using socket.io-event btw to capture all event, is something wrong with my code?
You can't send function like that.
What you can do is to JSON.stringify it and on the server call eval() on it.
Remember that it's dangerous. Anybody could send some code to your server and execute it.

Can't send message to only one specific room through node.js and socket.io

I have a problem that i don't seems to be able to solve it. I'm doing some kind of integration with remote system and my code is in iframe but that can't be important for this one i hope :).
I'm trying to send a message from server to specific room/client to begin session. First thing I do is when user log in, I emit message from client side with username.
CLIENT.JS
conn.on('connect', function () {
conn.emit('session', { username: 'some_username' });
}, false);
And on server side i get message and join socket to the room.
SERVER.JS
socket.on('session', function(session) {
socket.join(session.username);
});
I have another module that communicates with this server.js script through redis. So i have two more events in server.js
SERVER.JS
var userCreate = redis.createClient();
userCreate.subscribe("userCreate", "userCreate");
var userDestroy = redis.createClient();
userDestroy.subscribe("userDestroy", "userDestroy");
userCreate.on("message", function(channel, data) {
socket.to(JSON.parse(data).username).emit('beginSession', data);
});
userDestroy.on("message", function(channel, data) {
socket.to(JSON.parse(data).username).emit('endSession', data);
socket.leave(JSON.parse(data).username);
});
But when ever i try to emit message from server to client i broadcast message to everyone. What am I doing wrong?
Well, from the syntax point of view you are doing everything correct.
Didn't you forget to specify the userId property in the endSession?
userDestroy.on("message", function(channel, data) {
socket.to(JSON.parse(data).userId).emit('endSession', data);
socket.leave(JSON.parse(data).userId);
});
If that doesn't work - you should provide the contents of a data object

How to be sure that message via socket.io has been received to the client?

How to check that message sent with socket.io library has been received to the client.
Is there special method for it in socket.io?
Thanks for your answers!
You should use the callback parameter while defining the event handler.
A typical implementation would be as follows:
Client side
var socket = io.connect('http://localhost');
socket.emit('set', 'is_it_ok', function (response) {
console.log(response);
});
Server side
io.sockets.on('connection', function (socket) {
socket.on('set', function (status, callback) {
console.log(status);
callback('ok');
});
});
Now check the console on the server side. It should display 'is_it_ok'. Next check console on client side. It should display 'ok'. That's the confirmation message.
Update
A socket.io connection is essentially persistent. The following in-built functions let you take action based on the state of the connection.
socket.on('disconnect', function() {} ); // wait for reconnect
socket.on('reconnect', function() {} ); // connection restored
socket.on('reconnecting', function(nextRetry) {} ); //trying to reconnect
socket.on('reconnect_failed', function() { console.log("Reconnect failed"); });
Using the callback option shown above is effectively a combination of the following two steps:
socket.emit('callback', 'ok') // happens immediately
and on the client side
socket.on('callback', function(data) {
console.log(data);
});
So you don't need to use a timer. The callback runs immediately except if the connection has any of the following states - 'disconnect', 'reconnecting', 'reconnect_failed'.
You can use the socket.io's acknowledgements.
Quote from the socket.io documentation:
Sometimes, you might want to get a callback when the client confirmed
the message reception.
To do this, simply pass a function as the last parameter of .send or
.emit. What's more, when you use .emit, the acknowledgement is
done by you, which means you can also pass data along.
On the client side simply emit the event with your data, the function will be called whenever the server responds to your event:
client.emit("someEvent", {property:value}, function (data) {
if (data.error)
console.log('Something went wrong on the server');
if (data.ok)
console.log('Event was processed successfully');
});
On the server side you get called with the data and the callback handle to send the response:
socket.on('someEvent', function (data, callback) {
// do some work with the data
if (err) {
callback({error:'someErrorCode', msg:'Some message'});
return;
}
callback({ok:true});
});
When you add a function as the last parameter of .send() or .emit() method calls, this function is called when the other party receives the message.
socket.send('hi', function() {
// if we are here, our salutation has been received by the other party.
});

Categories

Resources