Cant create soap client on node - node.js

When accessing WSDL api via another tool it is working but when i try to create a client via node it gives this error.
{ [Error: Parse Error] bytesParsed: 161, code:
'HPE_INVALID_HEADER_TOKEN' }
Code i am using
var url = 'https://payments.jazzcash.com.pk/PayAxisExternalStatusService/StatusService_v11.svc?wsdl';
soap.createClient(url, function(err, client) {
console.log(err);
console.log(client); })
Using node module soap

You might need to use https://www.npmjs.com/package/http-parser-js
1 npm install http-parser-js
2 Insert this code before require('soap')
process.binding('http_parser').HTTPParser = require('http-parser-js').HTTPParser;
Following above steps will fix your issue

Node.js is really strict about response format of the server.
I tried http-parser-js but it is very sensitive to the version of Node.js you use.
If you need to communicate with the server which sends malformed responses the only way I see is to use sockets:
const net = require('net');
const socketConnection = net.createConnection('80', 'google.com');
socketConnection.on('data', (data) => {
console.log('SOCKET RESPONSE', data.toString());
}).on('connect', () => {
const request = "GET / HTTP/1.1\r\n"
+ "Accept: */*\r\n\r\n";
socketConnection.write(request);
console.log('request sent');
}).on('end', () => {
console.log('the end');
}).on('error', (error) => {
console.log('connection error:', error);
});
In the context of the SOAP client, you can get WSDL yourself and store it locally and then create a SOAP client.

Related

Socket hang up when connecting to websocket with Node.JS and a WebSocketsClient

I'm trying to connect to a public websocket to retrieve a stream of data using Node.JS and the WebSocketClient.
Using Chrome extension tools such as WebSocket Test Client and PieSocket Websock Tester, I am able to do this successfully. I can enter the websocket URL, connect and receive am initial header of data and then when I send the required response to initiate the data stream, I can see the data being received every second, as expected.
I then created a simple Node.JS app to do the same as above so that I can get the data from the websocket and work with it but I keep getting a
Connect Error: Error: socket hang up
I have debugged the code and stepped through it but I can't see why this is happening. I can only assume at this point that it's not keeping the connection open but despite researching how to do this, I can't find a way (if indeed this is the issue?).
This is the code I am using so far just to test the retrieval of the data:
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
const _Message = JSON.stringify(
{
Key: '123',
Format: 'JSON'
});
client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
client.on('connect', function(connection) {
connection.send(_Message);
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
});
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + message.utf8Data + "'");
}
});
function sendData() {
if (connection.connected) {
console.log("STILL CONNECTED");
}
}
sendData();
});
client.connect('ws://URLofWebsocket:3030/PathToWebsocket/', 'echo-protocol');
I've been trying to fix this issue for 2 days so any advice would be appreciated.
I have tried 2 different Websocket libraries but get the same error.

How to execute a NestJs TCP Microservice command by nodeJs

I have a working Microservice(MS) based on https://docs.nestjs.com/microservices/basics using a TCP protocol. Executing a command from my NestJS API was easy by implementing the #nestjs/microservices Client.
Now im working on a Lambda (AWS) in plain nodeJs, this lambda contains a function that also need to send a command to the MS. I tried using net to create a Socket to send a command (stringified) but it doesn't trigger anything.
my example nodeJs code:
const net = require('net');
const saveProducts = (products) => {
let socket = new net.Socket();
socket.setEncoding('UTF8');
socket.on('data', function (data) {
console.log('ON DATA'); // print out data
console.log(data.toString()); // print out data
});
socket.connect(options.port, options.host, function () {
//called when connection is created
const command = JSON.stringify({ pattern: { cmd: 'update-many', ctrl: 'product' } });
socket.write(command, 'UTF8', function (err) {
console.log(err);
});
});
}
I have used a network sniffer to get an example message structure..
similar issue but the suggestion is only to add #nestjs/microservices, I was wondering how to do it without it.
After some long research found out what the pattern is what you need to send:
[MSG_LEN]#{ pattern: "[PATTERN_STRING]", data: "[DATA]", id: "[ID]" }
Example:
62#{"pattern":"find","id":"ce51ebd3-32b1-4ae6-b7ef-e018126c4cc4"}
The parameter id is for #MessagePattern, without it #EventPattern will be triggered.

Timeout error when calling API from Nodejs

I am calling this public API from my nodejs. I am using system in office enviornment and I have to connect with VPN to accress office url. When I use wifi of my mobile then I can access below API.
https://dummy.restapiexample.com/api/v1/employees
the above is public API. anybody can check.
I have to use https to access API in node because of security reasons. How can i access the API when I am in my office enviornment. I am getting below error.
Error:connect ETIMEDOUT 52.220.246.189:443.
below is the code.
const https = require('https');
https.get('https://dummy.restapiexample.com/api/v1/employees', (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
console.log(data);
});
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
});
console.log("data");
}).on("error", (err) => {
console.log("Error: " + err.message);
});
How can I resolve the same?

create server with node and get endpoint with React Native

I have json file and created node.js server to set endpoint and then get this data via my React Native application. If I'm not wrong it worked correctly in friday but I had to mess something up and now I totally don't know how to fix it. All time I get error:
Possible Unhandled Promise Rejection (id: 0): TypeError: Network
request failed
self.fetch/http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:27859:18
dispatchEvent#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:29144:13
setReadyState#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:28897:15
__didCompleteResponse#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:28724:11
send/<#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:28834:18
emit#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:4538:15
__callFunction#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:2608:22
callFunctionReturnFlushedQueue/<#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:2385:11
__guard#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:2561:13
callFunctionReturnFlushedQueue#blob:http://192.168.1.39:8081/1c49a23b-7fbb-c640-a946-c1e001192c92:2384:9
onmessage#http://192.168.1.39:8081/debugger-ui/debuggerWorker.js:72:25
my Node server:
const filename = './logos.json';
const server = http.createServer((req, res) => {
if (req.url === "/logo") {
res.writeHead(200, { "Content-Type": "application/json" });
fs.createReadStream(__dirname + "/logos.json").pipe(res)
}
})
server.listen(3000, (err) => {
if (err) throw err;
console.log('server is listening on port 3000');
})
and my RN code :
syncLogoData = () => {
fetch('http://localhost:3000/logo')
.then(resp => resp.json())
.then(data => console.log(data))
.catch(err => console.log(err))
}
Looks like you're trying to run this on a device. The device doesn't know localhost points to your server. In your syncLogoData, change the uri to http://ip_address:3000/logo and it should work.
Also helpful to open http://localhost:3000/logo on your computer browser to make sure your server code is correct.

Making an HTTPs request on AWS ApiGatewayV2 websocket connection to Respond, or Delete it

UPDATE
This issue is partially resolved, the problem now lies in authenticating the ApiGateway request. I am unsure of how to acquire the necessary tokens to send with the request so that it is valid, because this is a [serverless-framework] service so I can't use the AWS Console to copy paste the tokens into the request's json data. Moreover, I wouldn't know what json key they'd have to be under anyways. So I guess this question has changed considerably in scope.
I need to respond/delete an active websocket connection established through AWS ApiGatewayV2, in a Lambda. How do I use node js to send a POST request that ApiGateway can understand?
I saw on the websocket support announcement video that you could issue an HTTP POST request to respond to a websocket, and DELETE request to disconnect a websocket. Full table from the video transcribed here:
Connection URL
https://abcdef.execute-api.us-west-1.amazonaws.com/env/#connections/connectionId
Operation Action
POST Sends a message from the Server to connected WS Client
GET Gets the latest connection status of the connected WS Client
DELETE Disconnect the connected client from the WS connection
(this is not documented anywhere else, AFAIK)
Seeing as the AWS SDK does not provide a deleteConnection method on ApiGatewayManagementApi, I need to be able to issue requests directly to the ApiGateway anyways.
const connect = async (event, context) => {
const connection_id = event.requestContext.connectionId;
const host = event.requestContext.domainName;
const path = '/' + event.requestContext.stage + '/#connections/';
const json = JSON.stringify({data: "hello world!"});
console.log("send to " + host + path + connection_id + ":\n" + json);
await new Promise((resolve, reject) => {
const options = {
host: host,
port: '443',
path: path + connection_id,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(json)
}
};
const req = https.request(
options,
(res) => {
res.on('data', (data) => {
console.error(data.toString());
});
res.on('end', () => {
console.error("request finished");
resolve();
});
res.on('error', (error) => {
console.error(error, error.stack);
reject();
});
}
);
req.write(json);
req.end();
});
return success;
};
When I use wscat to test it out, this code results in the console.log showing up in CloudWatch:
send to ********.execute-api.us-east-2.amazonaws.com/dev/#connections/*************:
{
"data": "hello world!"
}
...
{
"message": "Missing Authentication Token"
}
...
request finished
And wscat says:
connected (press CTRL+C to quit)
>
But does not print hello world! or similar.
Edit
I was missing
res.on('data', (data) => {
console.error(data.toString());
});
in the response handler, which was breaking things. This still doesnt work, though.
You're likely missing two things here.
You need to make an IAM signed request to the API Gateway per the documentation located here: Use #connections Commands in Your Backend Service
You'll need to give this lambda permission to invoke the API Gateway per the documentation here: Use IAM Authorization
I hope this helps!

Resources