I want to communicate my nodejs backend with frontend with laravel-echo and pusher
I need to use laravel because backend developer has created a php backend with laravel, and he passed me the pusher information and i put them in .env
the doc of laravel isnt very helpful on this, maybe i am too new to this, I followed the way in the doc to create an echo connection with pusher with the code the below. But i got an error saying Echo is not a constructor.
The flow goes like this, frontend A.html will call a fetch to trigger the nodejs backend to run a python script. upon the python script returned stdout, will trigger nodejs backend to post a message to a frontend B.html that is listening to the laravel channel.
in the frontend B.html:
<script>
var channel = Echo.channel('chat');
channel.listen('response', function (data) {
console.log(JSON.stringify(data));
<<do sth with the data>>
</script>
in the nodejs backend index.js:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
import axios from 'axios';
global.axios = axios;
global.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
global.pusher = Pusher;
global.Echo = new Echo({ //throw 'Echo is not a constructor' error
broadcaster: 'pusher',
key: VITE_PUSHER_APP_KEY,
cluster: VITE_PUSHER_APP_CLUSTER,
forceTLS: VITE_PUSHER_SCHEME,
wsPort: 80,
wssPort: 443,
});
var channel = Echo.channel('chat');
channel.listen('response', function (data) {
console.log(JSON.stringify(data));
app.get('/record', (req, res) => {
const pyProg = spawn('python', ['script.py']);
pyProg.stdout.on('data', function (data) {
const data_string = data.toString();
const data_json = JSON.parse(data_string);
const message = data_json.message;
axios.post('/api/post', {
type: 'MESSAGE',
value: message,
}).then(function (response) {
console.log(response);
message.value = "";
}).catch(function (error) {
console.log(error);
});
return res.json({ success: true, data: data_string });
});
});
My questions are
How can i connect to the laravel backend with laravel-echo and pusher and then broadcast a message from node backend to frontend that is listening to the channel?
What is the proper way to create the echo channel in nodejs backend?
Thanks
Related
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.
i want to integrate pubnub with reactjs frontend and node js backend.My system consist of websocket . I want to replace websocket with pubnub connection .I have installed pubnub using npm in node js its works fine.But in front end side when i run npm start i see only below screen.
The problem with web socket is when connection lost i didnt get back my card details(poker game cards)
Did i do something wrong?if please let me know correct way to do it.
i have replaced websocket connection of existing system with pubnub.see code below.
import PubNub from 'pubnub';
import { PubNubProvider, usePubNub } from 'pubnub-react';
// import CountDownBgTask from "./containers/CountDownBgTask";
const pubnub = new PubNub({
publishKey: 'xxxxxxxxxxxxxxxxx',
subscribeKey: 'xxxxxxxxxxxxxxxxx'
});
componentDidMount() {
if (isMobile) {
setTimeout(() => {
this.setState({
isOpen: true
});
window.scrollTo(0,1);
},1000)
}
window.onbeforeunload = closingCode;
// Read res from service via Socket IO
// socket.on("message", receiveMsg);
pubnub.on("message", text => {
let params = text.split("|"); //.map(p => Base64.Decode(p)); // we are not using b64 now
let message = params.shift(); // message, eg. playerSitOut, clearTable
this.receiveMsg.push(message);
this.props.updateMessage({ message, params });
});
}
Context :
I have a WebSocket server program (.exe build with C#) and i want to test my request with a NodeJs client (in production mode, it will be NodeJs client app which going to use the "API") I use jest to test it
My test code :
const WebSocket = require('ws');
test('Extension Connection test', async ()=>{
var ws = new WebSocket("ws://127.0.0.1:2031/Extension");
await new Promise((resolve, reject)=>{
ws.onmessage = function (message) {
var responseAttended = {"type":"Information","data":{"information":"Success connection as Extension"},"target":"Extension"};
assert(message.data, responseAttended);
resolve();
};
ws.onopen = function () {
var request = {target: "ExtensionService", type: "Auth", data: {name: "extension"}};
ws.send(JSON.stringify(request));
};
ws.onerror = function () {
assert(false);
reject();
}
});
});
I started my server before launch test, my server catch the value send (so websocket is connected). My server did some stuff and send back the response, but it's looks like this one never arrived in my NodeJs test client
As no response arrived, the promise is not resolved and after 5s the jest timeout stop the test.
Any idea what i made bad ?
I think you can use jest.setTimeout(millisecond) before use test(), it work for me
jest.setTimeout(10000);
test('Extension Connection test', async () => {
// TODO your code
})
Following is my POST function in Node js. I want to call a funtion in my client side HTML to display an error message on the page.
router.post('/',(req,res)=>{
const data = JSON.stringify({
institute_name: req.body.institute_name,
email : req.body.email,
password : req.body.password
})
const options = {
host:'localhost',
port:'8888',
path:'/registerInstitute',
method:'POST',
headers: {
'Content-Type':'application/json'
}
}
const req1 = http.request(options, (res1)=>
{
const status = res1.statusCode
if (status == 201)
{
//admin created
res.redirect('/?account_created=true')
}
else if ( status == 409)
{
//CALL AJAX FUNCTION TO DISPLAY ERROR MSG
}
})
req1.write(data)
req1.end()
})
The simple answer is NO. But there are workarounds to do so and I've demonstrated the one that will suite your scenario
Sockets
You can use web sockets to trigger event to notify client to run specific function
On service side you can do something like this:
var io = require('socket.io').listen(80); // initiate socket.io server
if (
io.sockets.on('connection', function (socket) {
if ( error == 403 ) {
socket.emit('runErrorFunction', { error: "error data" });
}
});
You can do something like this on client side:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost'); // connect to server
socket.on('runErrorFunction', function (data) { // listen to runErrorFunction event raised by the server
// Here goes your error showing logic
});
</script>
Here is the link for more info Socket.io
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.