pubnub integration in react js frontend and nodejs backend - node.js

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 });
});
}

Related

how to create laravel-echo connection in nodejs with pusher?

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

Two different websockets working together

I'm trying to figure out how to implement a two separate websockets together. Not sure if this possible or not, but I have a websocket that works on it's own in from node.js file to angular another node.js file that uses Kraken (crypto exchange) websocket that also works in it's own file. I'm trying to consolidate them both together so that whenever a event onChange comes from Kraken websocket, I can relay that data to angular with angular socket.io websocket. Trying to do something like this
const webSocketClient = new WebSocket(connectionURL);
webSocketClient.on("open", function open() {
webSocketClient.send(webSocketSubscription);
});
webSocketClient.on("message", function incoming(wsMsg) {
const data = JSON.parse(wsMsg);
let io = require("socket.io")(server, {
cors: {
origin: "http://localhost:4200",
methods: ["GET", "POST"],
allowedHeaders: ["*"],
credentials: true,
},
});
io.on("connection", (socket) => {
const changes = parseTrades(data);
socketIo.sockets.emit(connection.change, changes);
Log whenever a user connects
console.log("user connected");
socket.emit("test event", JSON.stringify(changes));
});
console.log("DATA HERE", data[0]);
});
webSocketClient.on("close", function close() {
console.log("kraken websocket closed");
});
Although doing this doesnt relay the data to frontend and gives me a memory leak. Is there some way I can accomplish this?
I would probably split up the task a little bit. So have a service for the kraken websocket and maybe a service for your own socket, then have them communicate via observables, that you can also tap into from the front end to display data you want.
#Injectable()
export class KrakenService{
private webSocketClient : WebSocket | null;
private messages$ = new BehaviorSubject<any>(null); // give it a type
openConnection(){
// is connectionUrl from environment ??
this.webSocketClient = new WebSocket(connectionURL);
webSocketClient.on("open", function open() {
/// is webSocketSubscription from environment ??
webSocketClient.send(webSocketSubscription);
});
webSocketClient.on("message", function incoming(wsMsg) {
const data = JSON.parse(wsMsg);
this.messages$.next(data);
console.log("DATA HERE", data[0]);
});
webSocketClient.on("close", function close() {
console.log("kraken websocket closed");
this.webSocketClient = null;
});
}
getKrakenMessages(){
if(webSocketClient == null) this.openConnection();
return messages$.asObserbable();
}
}
So now when you want to either read the web socket messages or use them with the other socket you just subscribe to the krakenService.getKrakenMessages();
Then you can do something similar with you local service as well. Have something that opens connections, and one that emits messages. The example you showed it would open up a connection every time you got a message, so keep those logics separated. And reuse existing connection.

How to connect socket.io to a non-website application?

I made a discord bot (with discord.js) and i want to connect it with socket.io to send and receive a message from a website.
For website I use express.
How to connect socket.io to a non-website application?
If you want to use the websocket protocol to send and receive messages from a web page, you should use the built in WebSocket class. Your code can look something like this:
const socekt = new WebSocket("ws://[INSERT YOUR SERVER ADDRESS HERE]", ["wamp"]);
socket.onopen = () => {
//code to be executed, when the websocket connection was opened
console.log("Connection made!");
}
socket.onmessage = event => {
//code to be executed, when a message is recieved.
console.log(event.data);
}
socket.onclose = event => {
//code to be executed, when the connection is closed
console.log(`Connection closed with code ${event.code}.`);
}
//function to send a message via the websocket
function sendMessage(message) {
socket.send(message);
}

Socket.io: Other client only updates when being interacted

I'm trying to set up a realtime application using socket.io in Angular and node.js, which is not working as intended.
Whenever a client is making a new post, the other clients won't update until you interact with the client (e.g. clicking somewhere on the page, or clicking on the browsers tab).
However, having console open in the browser, I can see the new post in the console when I log the posts/objects - without the need to interact with the clients.
Angular:
import io from 'socket.io-client';
const socket = io('http://localhost:3000');
posts: Post[] = [];
...
// Inside ngOnInit:
socket.on('data123', (res) => {
console.log('Updating list..', res);
this.postService.getPosts();
this.postsSub = this.postService.getPostUpdateListener()
.subscribe((posts: Post[]) => {
this.posts = posts;
});
});
Displaying in the template:
<... *ngFor="let item of posts">
Inside PostsService:
getPosts() {
this.http.get<{ message: string, posts: Post[] }>('http://localhost:3000/api/posts')
.subscribe((postData) => {
this.posts = postData.posts;
this.postsUpdate.next([...this.posts]);
});
}
Node.js - this socket.io solution is not yet sending the actual list:
const io = socket(server);
io.sockets.on('connection', (socket) => {
console.log(`new connection id: ${socket.id}`);
sendData(socket);
})
function sendData(socket){
socket.emit('data123', 'TODO: send the actual updated list');
setTimeout(() => {
console.log('sending to client');
sendData(socket);
}, 3000);
}
What worked as intended:
Using setInterval instead "socket.on(..)" on the front-end gave the intended result, meaning the clients will update automatically without the need of interacting. I'm fully aware this solution is horrible, but I assume this pinpointing that it's something wrong with socket solution above in Angular part.
wait, every time when socket.on('data123', (res) => {... you are creating new subscribe? it's wrong way...you must create subscribe in your socket connect feature

Vue Socket.io Not Receiving Data

I currently have a Python Flask SocketIO application that will be connecting to a Vue app using this socket.io library. The Vue app (currently) will poll the Python application using socket.io on a button press. I can correctly receive the data sent from Vue; however, Vue is not receiving the data. Currently, my actions/mutations looks like this:
const actions = {
fbCommentsPerPost: (context) => {
console.log('fb comments per post sent!')
socket.emit('fb comments per post', { post_id: '123' })
// socket.on('data', function (resp) {
// console.log(resp)
// })
},
socket_connectResp: (context, message) => {
console.log(message)
},
socket_fbData: (context, message) => {
console.log(message)
}
}
// mutations
const mutations = {
SOCKET_FB_DATA: (state, status) => {
console.log('comments!!!!')
}
}
Using the README for this project, the socket_fbData should be receiving the data from the Python app (the backend is emitting 'fb data'). When I run a simple client in node using socket.io-client, this works and I can properly receive data. Moreover, when I uncomment the socket.on block in fbCommentsPerPost, I can at least console log the data. Is there something I'm missing here?
vue-socket.io has an issue with converting socket events to actions and mutations. It kind of works but not as expected. Check issue #117
A few months ago there was few PRs with a fix for this issue but some edge cases are not covered. So you can try the latest version or just move to vue-socket.io-extended instead.

Resources