Vue 3, Socket IO - not listening to event - vue.js

For server side I have following code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
console.log("user connected");
socket.on("join", function (room) {
console.log(room);
socket.join(room);
});
socket.on('newOrder', function (data) {
socket.emit('this', data)
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
and in the Vue (client side) I have following:
import VueSocketIO from 'vue-3-socket.io'
import SocketIO from 'socket.io-client'
export const useSocketIO = () => {
const socket = new VueSocketIO({
debug: true,
connection: SocketIO('http://localhost:3000')
})
return {
socket,
}
}
And in the component:
<script setup>
import { useSocketIO } from "#/services/socketio"
const { socket } = useSocketIO()
onMounted(async () =>
{
await socket.io.emit('join', 'servant')
socket.io.on('this', () =>
{
console.log('event this fired')
})
})
</script>
Event this is emitted from the server, but nothing is happening on the client side. What am I doing wrong here?

Related

Secure random number generation is not supported by this browser

I am trying to establish a peer-to-peer video connection between a web frontend and a react-native android smart tv app. I want to display the user's webcam video on the smart tv. I am using an express server for signaling:
const app = require("express")();
const server = require("http").createServer(app);
const cors = require("cors");
const io = require("socket.io")(server, {
cors: {
origin: "*",
methods: [ "GET", "POST" ]
}
});
app.use(cors());
const PORT = process.env.PORT || 8082;
//here we define the behaviour of the API Endpoints
app.get('/', (req, res) => {
res.send('Runnin');
});
app.post('/',(req,res) => {
const body = req.body;
res.send(body);
});
io.on("connection", (socket) => {
socket.emit("me", socket.id);
console.log(socket.id);
socket.on("disconnect", () => {
socket.broadcast.emit("callEnded")
});
socket.on("callUser", ({ userToCall, signalData, from, name }) => {
io.to(userToCall).emit("callUser", { signal: signalData, from, name });
});
socket.on("answerCall", (data) => {
io.to(data.to).emit("callAccepted", data.signal)
});
});
server.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
The signaling is working but as I am trying to display the video the following error is displayed:
[Link to screenshot of the error][1]
Code of the react-native Callscreen component:
import React, { useEffect, useState, useCallback, useContext } from 'react';
import { View, StyleSheet, Alert, Button, Text } from 'react-native';
import { RTCView } from 'react-native-webrtc';
import { SocketContext } from './Context';
import Callnotification from './Callnotifcation';
function CallScreen(props) {
const { callAccepted, userVideo, callEnded, me } = useContext(SocketContext);
return (
<>
{callAccepted && !callEnded && (
<View style={styles.root}>
<View style={[styles.videos, styles.remoteVideos]}>
<Text>Video of the caller</Text>
<RTCView streamURL={JSON.stringify(userVideo)} style={styles.remoteVideo} />
</View>
</View>
)
}
<View style={styles.root}>
<Callnotification />
<Text>{JSON.stringify(me)}</Text>
</View>
</>
);
}
Code of the Context.js connecting the react-native app to the signaling server:
import React, { createContext, useState, useRef, useEffect } from 'react';
import { io } from 'socket.io-client';
import Peer from 'simple-peer';
const SocketContext = createContext();
const socket = io('http://10.0.2.2:8082'); // use this to access via android emulator
//const socket = io('http://192.168.178.106:8082'); //use this to access via SmartTv Fire Tv Stick
const ContextProvider = ({ children }) => {
const [callAccepted, setCallAccepted] = useState(false);
const [callEnded, setCallEnded] = useState(false);
const [stream, setStream] = useState();
const [name, setName] = useState('');
const [call, setCall] = useState({});
const [me, setMe] = useState('');
const userVideo = useRef();
const connectionRef = useRef();
useEffect(() => {
socket.on('me', (id) => setMe(id));
socket.on('callUser', ({ from, name: callerName, signal }) => {
setCall({ isReceivingCall: true, from, name: callerName, signal });
});
}, []);
const answerCall = () => {
setCallAccepted(true);
const peer = new Peer({ initiator: false, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('answerCall', { signal: data, to: call.from });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
};
/* const callUser = (id) => {
const peer = new Peer({ initiator: true, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('callUser', { userToCall: id, signalData: data, from: me, name });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
socket.on('callAccepted', (signal) => {
setCallAccepted(true);
peer.signal(signal);
});
connectionRef.current = peer;
};*/
const leaveCall = () => {
setCallEnded(true);
connectionRef.current.destroy();
};
return (
<SocketContext.Provider value={{
call,
callAccepted,
setCallAccepted,
userVideo,
stream,
name,
setName,
callEnded,
me,
leaveCall,
answerCall,
}}
>
{children}
</SocketContext.Provider>
);
};
export { ContextProvider, SocketContext };
Code of the Context.js connecting the web react frontend to the signaling server:
import React, { createContext, useState, useRef, useEffect } from 'react';
import { io } from 'socket.io-client';
import Peer from 'simple-peer';
const SocketContext = createContext();
// const socket = io('http://localhost:5000');
const socket = io('http://localhost:8082');
const ContextProvider = ({ children }) => {
const [callAccepted, setCallAccepted] = useState(false);
const [callEnded, setCallEnded] = useState(false);
const [stream, setStream] = useState();
const [name, setName] = useState('');
const [call, setCall] = useState({});
const [me, setMe] = useState('');
const myVideo = useRef();
const userVideo = useRef();
const connectionRef = useRef();
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then((currentStream) => {
setStream(currentStream);
myVideo.current.srcObject = currentStream;
});
socket.on('me', (id) => setMe(id));
socket.on('callUser', ({ from, name: callerName, signal }) => {
setCall({ isReceivingCall: true, from, name: callerName, signal });
});
}, []);
const answerCall = () => {
setCallAccepted(true);
const peer = new Peer({ initiator: false, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('answerCall', { signal: data, to: call.from });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
};
const callUser = (id) => {
const peer = new Peer({ initiator: true, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('callUser', { userToCall: id, signalData: data, from: me, name });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
socket.on('callAccepted', (signal) => {
setCallAccepted(true);
peer.signal(signal);
});
connectionRef.current = peer;
};
const leaveCall = () => {
setCallEnded(true);
connectionRef.current.destroy();
window.location.reload();
};
return (
<SocketContext.Provider value={{
call,
callAccepted,
myVideo,
userVideo,
stream,
name,
setName,
callEnded,
me,
callUser,
leaveCall,
answerCall,
}}
>
{children}
</SocketContext.Provider>
);
};
export { ContextProvider, SocketContext };
In my opinion the error lies in the RTCView of the Callscreen but i have no idea how to fix it. Your help is very much appreciated!
Thank you very much!
[1]: https://i.stack.imgur.com/YBh9P.jpg
The library that you are using is probably using the SubtleCrypto.generateKey function to generate shared secrets. This API is "only available in a secure context", which means that it can only be used if the page is served over HTTPS.
Serve your page over HTTPS, and the error should go away.

axios doesn't send post for Stripe

I have a problem with axios Post. I work on adding Stripe payment to my page, but i send me axios error 404.
Maybe somebody can help me, I stuck on it for week already and cant just solve it.
Here is the code:
import React from 'react'
import StripeCheckout from 'react-stripe-checkout';
import { useState, useEffect } from "react";
import { useNavigate } from 'react-router-dom';
import axios from "axios";
const Pay = () => {
const [stripeToken, setStripeToken] = useState(null)
const navigate = useNavigate()
const onToken = (token) => {
setStripeToken(token);
}
useEffect(() => {
const makeRequest = async () => {
try {
const res = await axios.post(
"http//:localhost:5001/api/checkout/payment",
{
tokenId: stripeToken.id,
amount: 6000,
});
console.log(res.data)
} catch (err) {
console.log(err)
}
};
stripeToken && makeRequest()
}, [stripeToken]);
return (
<div className='pay__div'>
{stripeToken ? (<span>Processing</span>) : (
<StripeCheckout
name="Kate store"
image=""
billingAddress
shippingAddress
description="Yout total is $60"
amount={2000}
token={onToken}
stripeKey={KEY}
>
<button>Pay</button>
</StripeCheckout>
)}
</div>
)
}
export default Pay
Thank you for your time.
Also here are stripe.js index.js pages from backend
stripe.js
const router = require("express").Router();
const stripe = require("stripe")(process.env.STRIPE_KEY);
router.post("/payment", (req, res) => {
stripe.charges.create({
sourse: req.body.tokenId,
amount: req.body.amount,
currency: "usd"
},
(stripeErr, stripeRes) => {
if (stripeErr) {
res.status(500).json(stripeErr);
} else {
res.status(200).json(stripeRes);
}
});
});
module.exports = router;
And index.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const userRoute = require("./routes/user");
const authRoute = require("./routes/auth");
const productRoute = require("./routes/product");
const cartRoute = require("./routes/cart");
const orderRoute = require("./routes/order");
const stripeRoute = require("./routes/stripe");
const cors = require("cors");
dotenv.config();
mongoose.connect(process.env.MONGO_URL)
.then(() => console.log("DB Connected Successfull!"))
.catch((err) => {
console.log(err);
})
app.use(cors());
app.use(express.json());
app.use("/api/user", userRoute);
app.use("/api/auth", authRoute);
app.use("/api/product", productRoute);
app.use("/api/cart", cartRoute);
app.use("/api/order", orderRoute);
app.use("/api/checkout", stripeRoute);
app.listen(process.env.PORT || 5001, () => {
console.log("Backend is running")
})
Had the same problem. Moved dotenv.config(); before const stripeRoute = require("./routes/stripe"); in index.js and worked.

SocketIO auth and ReactNative

I have a module whith the connection:
import { createContext } from 'react';
import SInfo from 'react-native-sensitive-info';
import io from 'socket.io-client';
export const socket = io('http://192...', {
forceNew: true,
auth: {
token: 'eyJhbGciO...'
},
});
export const SocketContext = createContext(undefined);
But my token is saved by lib react-native-sensitive-info and i need to get it by
await SInfo.getItem('token', {});
My question is: How can I use await to get the token I need to export the socket?
Something like this:
export const socket = io('http://192...', {
forceNew: true,
auth: {
token: await SInfo.getItem('token', {});
},
});
Thanks in advance :D
Try this:
export const socket = async () => {
const token = await SInfo.getItem('token', {});
return io('http://192...', {
forceNew: true,
auth: {
token,
},
});
}
or
export const createSocket = (token) => {
return io('http://192...', {
forceNew: true,
auth: {
token,
},
});
}
and then use it in this way:
const token = await SInfo.getItem('token', {});
const socket = createSocket(token)

fetch POST request is pending (sending data from registration form)

I know that similar questions have already been here, but I didn't find anything for my problem.
I am creating project using [Webpack-Express-Pug-VanillaJS] stack of technologies.
I'm trying to make POST-request to send formData to '/api/users' using fetch a push data to array in my express file, but its only pending...
What kind of problems it can be?
client-side code
document.addEventListener('DOMContentLoaded', () => {
async function postData(url, data) {
try {
console.log('addEventListener works!')
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
console.log('fetch works!')
return await response.json()
} catch(e) {
console.warn('Error',e.message)
}
}
const forms = document.getElementsByTagName('FORM');
for (let i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(e) {
console.log(forms[i])
e.preventDefault();
let formData = new FormData(this);
formData = Object.fromEntries(formData);
console.log(formData) return object like {name:'Zhanna', age:25, email:'123zhanna#gmail.com'}
postData('/api/users', formData).then(data => console.log('Successful!'))
})
}
})
server-side
const path = require('path')
const express =require('express')
const webpack = require('webpack')
const bodyParser = require('body-parser')
const users = require('../routes/userInfo')
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from '../../webpack.dev.config.js'
import { v4 } from 'uuid';
const PORT = process.env.PORT || 8080
const app = express(),
compiler = webpack(config)
app.use(users.router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.json());
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'pug');
app.locals.basedir = __dirname;
app.use('/assets',express.static(path.join(__dirname,'assets')))
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
})
)
app.use(webpackHotMiddleware(compiler))
app.get('/registration', (req,res)=> {
res.status(200).render('registration')
})
app.get('/login', (req,res)=> {
res.status(200).render('signIn')
})
app.get('/', (req, res) => {
res.status(200).render('index')
}
)
app.get('/api/users', (req,res)=> {
res.status(200).json(users.list)
})
app.post('/api/users', (req,res)=> {
const user = {...req.body, id:v4()}
users.list.push(user)
console.log('Data was sent')
res.status(201).json(user)
})
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
And in my console there is only 3 logs:
addEvent listener works!
<form class="registration--form" id="send-form">...<form>
3.{name: "Zhanna", surname: "Kaymedenova", gender: "female", brth: "07.01.1994", email: "zh.kaymed#gmail.com"}

How to mock axios call within a method?

I am trying to mock an axios call within a vuejs method. Is this possible?
Here is my vue component (SomeObj):
methods:{
callAxiosMethod() {
const callApi= axios.create();
callApi.defaults.timeout = 10000;
callApi.get(mockedUrl)
.then(response => {
console.log('response is ' + response);
})
.catch(e => {});
}
}
Here is my spec.js
let mockData = {};
beforeEach(() => {
jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve(mockData));
});
let wrapper = shallowMount(SomeObj, {
stubs: [], localVue, mocks: {
mockUrl: mockUrl,
$route: {
params: { testId: "123" }
}
}
});
it('is a Vue instance', () => {
expect(wrapper.isVueInstance()).toBeTruthy();
axios.get.mockResolvedValue(mockData);
wrapper.vm.callAxiosMethod();
})
When I looked at the coverage, the system says the callApi is not covered. Any idea on how I can mock the axios call within the function?
Your code calls axios.create so you need to mock that function to return a mock callApi object.
Here is a simplified working example:
code.js
import * as axios from 'axios';
const mockedUrl = 'http://mock-url';
export const callAxiosMethod = () => {
const callApi = axios.create();
callApi.defaults.timeout = 10000;
return callApi.get(mockedUrl); // <= return the Promise so it can be awaited
}
code.test.js
import { callAxiosMethod } from './code';
jest.mock('axios', () => ({
create: jest.fn().mockReturnValue({
defaults: {},
get: jest.fn().mockResolvedValue('mocked data')
})
}));
test('callAxiosMethod', async () => { // <= async test function
const response = await callAxiosMethod(); // <= await the Promise
expect(response).toBe('mocked data'); // Success!
});