This is my client-side code base. It is working with one of the exchange websockets but not working with this websocket. Any suggestions?
websocket reference: https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md
import React, { Component, createContext } from "react";
export const Contx = createContext();
export class ConProvider extends Component {
state = {
coins: [],
digCoin: [],
sou: [],
passSocket: undefined
};
componentDidMount() {
this.socketCall();
}
socketCall = () => {
var ws = new WebSocket("wss://stream.binance.com:9443");
var msg = {
"method": "SUBSCRIBE",
"params": "btcusdt#depth",
"id": 1
};
ws.onopen = () => {
ws.send(msg);
};
ws.onmessage = e => {
const value = e.data;
this.setState({
coins: value
});
};
this.setState({
passSocket: ws
});
};
socketClose = () => {
var wss = this.state.passSocket;
wss.close();
};
render() {
console.log(this.state.coins);
// console.log(this.state.coins)
return (
<Contx.Provider
value={{
...this.state,
socketCall: this.socketCall,
socketClose: this.socketClose
}}
>
{this.props.children}
</Contx.Provider>
);
}
}
const ws = new WebSocket('wss://stream.binance.com:9443/ws');
const msg = {
method: 'SUBSCRIBE',
params: ['btcusdt#depth'],
id: 1,
};
ws.onopen = () => {
ws.send(JSON.stringify(msg));
};
Send accepts JSON format, I changed msg to object, passed the array to params and added /ws as mentioned above.
Try with
var ws = new WebSocket("wss://stream.binance.com:9443/ws");
Related
I'm making an React app that uses JsSip library in order to make and receive calls.
I've made two components, one for making the call, and the other for answering, I'm trying to test them locally, but Answer component doesn't log any incoming calls.
The first one is Phone.tsx component for making calls
import React, { useState, useEffect, useRef } from "react";
import JsSIP from "jssip";
import { OutgoingRTCSessionEvent, UA } from "jssip/lib/UA";
const Phone = () => {
const videoRef = useRef<HTMLVideoElement>(null);
// Create our JsSIP instance and run it:
const socket = new JsSIP.WebSocketInterface("ws://localhost:3000");
const configuration = {
sockets: [socket],
uri: "sip:alice#example.com",
password: "superpassword",
register: true,
};
const userAgent = new JsSIP.UA(configuration);
console.log(userAgent);
userAgent.start();
userAgent.on("connected", function (e) {
console.log("session started");
});
userAgent.on("disconnected", function (e) {
console.log("session ended");
});
userAgent.on("newRTCSession", function (e: OutgoingRTCSessionEvent) {
console.log("RTC session initiated");
});
const getAudio = () => {
navigator.mediaDevices
.getUserMedia({ audio: true })
.then((stream) => {
let audio = audioRef.current;
if (!audio) return;
audio.srcObject = stream;
audio.play();
})
.catch((err) => console.log(err));
};
const handleCall = () => {
getAudio();
const options = {
mediaConstraints: { audio: true, video: false },
};
userAgent.call("sip:bob#example.com", options);
};
return (
<div>
<button onClick={() => handleCall()}>Call</button>
<audio ref={audioRef}></audio>
</div>
);
};
export default Phone;
And the Answer.tsx component for receiving the calls
import React, { useState, useEffect } from "react";
import JsSIP, { UA } from "jssip";
import { IncomingRTCSessionEvent } from "jssip/lib/UA";
const Answer = () => {
const socket = new JsSIP.WebSocketInterface("ws://localhost:3000");
const configuration = {
sockets: [socket],
uri: "sip:bob#example.com",
password: "secret",
};
const userAgent = new JsSIP.UA(configuration);
userAgent.start();
userAgent.on("newRTCSession", (e: IncomingRTCSessionEvent) => {
const session = e.session;
if (session.direction === "incoming") {
console.log("Incoming call from", session.remote_identity.uri.toString());
session.answer({
mediaConstraints: { audio: true, video: false },
});
}
});
return <div>Ready to receive calls!</div>;
};
export default Answer;
I'm running Phone component in one browser, and Answer in another. I'm getting weird audio sounds and echoes once I invoke the getAudio() function, so I'm not sure if it's getting streamed properly to Answer component.
I am attaching all the function snippets below. I am using jest to run a unit test on this function but this needs to mock axios. I tried like this :
// TODO - mock axios class instance for skipped Test suites
describe("dateFilters()", () => {
beforeEach(() => {
jest.resetAllMocks();
});
it("Mock Fetch API for Date Options Response", async () => {
const mockFn = jest.fn();
setUpMockResponse(mockFn, mockFetchDateOptionsResponse);
const response = await dateFilters(Workload.WIN32);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(response?.data).toEqual(mockFetchDateOptionsResponse);
});
});
The error I am getting is :
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
It seems it is not mocking anything.
All the require function definitons are below:
export const dateFilters = async (platform) => {
const dates = await getKustoResponse({
queryName: platform.toLowerCase().concat("DateFilters"),
platform,
queryParams: {},
});
return dates;
};
export const getKustoResponse = async ({
queryName,
platform,
queryParams,
cluster = "Default",
}: QueryDetail) => {
const dbName = getClusterValue({ platform, cluster, key: "db" });
const url = getClusterValue({ platform, cluster, key: "kustoUrl" });
const postBody = {
db: dbName,
csl: queryParams
? substituteQueryParameters(queries[queryName], queryParams)
: queries[queryName],
};
const apiClient = ApiClient.getInstance();
const response = await apiClient.post(url, postBody, {
headers: {
...kustoApiRequestDefaultConfiguration.headers,
"x-ms-kql-queryName": queryName,
},
timeout: kustoApiRequestDefaultConfiguration.timeout,
});
return response;
};
import Axios, { AxiosInstance } from "axios";
import axiosRetry from "axios-retry";
export class ApiClient {
private static instance: AxiosInstance;
public static getInstance = (): AxiosInstance => {
if (!ApiClient.instance) {
ApiClient.createInstance();
}
return ApiClient.instance;
};
private constructor() {
ApiClient.getInstance();
}
protected static createInstance = () => {
const responseType = "json";
const client = Axios.create({
responseType,
});
axiosRetry(client, apiRetryConfiguration);
client.interceptors.request.use(requestInterceptor);
client.interceptors.response.use(responseInterceptor, errorInterceptor);
ApiClient.instance = client;
};
}
export const requestInterceptor = async (
request: AxiosRequestConfig
): Promise<AxiosRequestConfig> => {
const token = await getKustoToken();
request.headers = { ...request.headers, Authorization: `Bearer ${token}` };
return request;
};
There is no fetch call in your source code. Is it in the apiClient? If so, do this:
jest.spyOn(apiClient, 'post').mockImplementation();
expect(apiClient.post).toHaveBeenCalled();
I am building a todo-app using React. I am dispatching an action(COMPLETED_TASK) to reducer after request/response from firestore DB. Since I'm also using redux-logger I noticed that this action is running twice.
Here's the code for Action:
export const completedTask = (data, completedBool) => async (
dispatch,
getState
) => {
try {
const formObj = cloneDeep(data);
const onlyDate = formObj.taskTime;
const getId = formObj._id;
const getDate = cleanDate(onlyDate, 'DD');
const getMonth = cleanDate(onlyDate, 'MM');
const getYear = cleanDate(onlyDate, 'YYYY');
const { uid } = getState().firebase.auth;
const todoUpdateString = `todoListByDate.${getDate}.${getId}.completed`;
await db.doc(`todos-col/${uid}&${getMonth}${getYear}`).update({
[todoUpdateString]: completedBool,
});
formObj.completed = completedBool;
dispatch({
type: todoTypes.COMPLETED_TASK,
payload: {
todosByMonthData: {
[`${getMonth}-${getYear}`]: {
[getDate]: { [getId]: formObj },
},
},
selectedDate: {
selectedDay: getDate,
selectedMonth: getMonth,
selectedYear: getYear,
},
},
});
} catch (err) {
console.log('Error!!', err);
}
};
In the screenshot, at 1, the action is dispatched to the reducer(it logs payload data from reducer below), and then again the action with type: "COMPLETED_TASK" is dispatched but it is not received by the reducer.
Why is this happening? Can anybody help?
I have been trying to create a authentication system in svelte , and signup is a multi-step process so need to save api response from step 1 and pass along , each step is a different route .Have came across store in svelte but somehow it just return undefined when fetching the data using get . Below is the demo code which returns the same ouput.
index.svelte
<script>
import signUpStore from "./hobby-store.js";
let data = {
name: "Rahul",
age: "something"
};
signUpStore.setSignUp(data);
// let result = signUpStore.getSignUp();
// console.log(result); //undefined
</script>
<p>
<strong>
Try editing this file (src/routes/index.svelte) to test live reloading.
</strong>
</p>
About.svelte
<script>
import signUpStore from "./hobby-store.js";
import { onMount } from "svelte";
let result = signUpStore.getSignUp();
console.log("server side : ", result); //undefined
onMount(() => {
console.log("client side : ", result); // undefined
});
</script>
<p>This is the 'about' page. There's not much here.</p>
hobby-store.js
import {
writable,
get
} from 'svelte/store'
const signUp = writable()
const signUpStore = {
subscribe: signUp.subscribe,
setSignUp: (items) => {
signUp.set(items)
// console.log('items : ', items, signUp)
},
addSignUp: (data) => {
signUp.update(items => {
return items.concat(data)
})
},
getSignUp: () => {
get(signUp)
}
}
export default signUpStore;
Just need to save this data in session or any persistent storage that svelte or sapper provides and reset it on successfull action.
Example session.js store below with logging:
import { writable } from 'svelte/store';
import { deepClone } from './../utilities/deepClone.js';
const newSession = {
a; 0, b: 0, x: 0
};
function sessionStore() {
const { subscribe, set, update } = writable(deepClone(newSession));
let logging = false;
return {
subscribe, // $session...
update: (obj) => {
update(o => { // session.update({a:1, b:2});
const merged = Object.assign(o, obj);
if (logging) console.log('session update', merged);
return merged;
});
},
set: (key, value) => { // session.set('x', 9)
update(o => {
const merged = Object.assign(o, {[key]: value});
if (logging) console.log('session set', merged);
return merged;
});
},
reset: () => { // session.reset()
set(deepClone(newSession));
},
set log(bool) { // setter: session.log = true;
logging = bool === true;
}
};
};
export const session = sessionStore();
Example.svelte
<script>
import { session } from './session.js';
session.log = true;
$: console.log('reactive log', $session);
session.set('x', 10);
session.reset();
<script>
I have a component that's state I'm trying to use in other components, it has to be used in multiple components so i'm switching it to redux. Right now using the same function that works in my component, I am getting the error 'newUsers.push is not a function'
Below is my redux action:
import { FETCH_USERS_TO_ADD } from './types';
import axios from 'axios'
export const fetchUsersToAdd = () => dispatch => {
var userBox = [];
var newUserBox = [];
let newUserIds = {};
let newUsers = [];
axios.all([
axios.get('/updateUserList'),
axios.get('/userInformation')
])
.then(axios.spread((newUsers, currentUsers) => {
userBox.push(newUsers.data)
newUserBox.push(currentUsers.data)
for (let newUser of newUserBox){
newUserIds[newUser.id] = newUser.id
}
for (let user of userBox){
if(!newUserIds[user.staffID]){
console.log(user)
**newUsers.push(user)**
}
}
})).then(dispatch({
type: FETCH_USERS_TO_ADD,
payload: newUsers
}))
}
The Code Below in My class component doesnt give me this error:
let newUserIds = {};
let newUsers = [];
this.state = {
userBox : [],
newUserBox : [],
usersToBeAdded:[],
}
componentDidMount(){
axios.all([
axios.get('/updateUserList'),
axios.get('/userInformation')
])
.then(axios.spread((newUsers, currentUsers) => {
this.setState({
userBox : newUsers.data,
newUserBox : currentUsers.data,
})
}))
}
checkForNewUsers = (e) => {
for (let newUser of this.state.newUserBox){
newUserIds[newUser.id] = newUser.id
}
for (let user of this.state.userBox){
if(!newUserIds[user.staffID]){
newUsers.push(user)
}
}
this.setState({
usersToBeAdded:newUsers
})
console.log(newUsers)
}
<UpdateUsersButton onClick={this.checkForNewUsers}/>
When user is consoled it returns an array like this:
Array(10)
0: {staffID: 1, dept: "Junior Web Developer", email: "manasaN#tpionline.com", name: "manasa", password: "$2y$10$/zYS7OhzwdLOi6Slzc3xxxxxiY0y1J6MjnLCN24GmZ3rMHWUS"}
1: {staffID: 2, dept: "Web Developer", email: "juliof#tpionline.net", name: "Julio Fajardo", password: "$2y$10$MphAC8aRY2uzs1Zxxxxxnd7t0KukEkvGbx5Y4van.Da6"}
I think it's because newUsers gets shadowed in the arrow function and isn't what you think it is anymore. Don't reuse variable names.
Try this:
import { FETCH_USERS_TO_ADD } from './types';
import axios from 'axios'
export const fetchUsersToAdd = () => dispatch => {
var userBox = [];
var newUserBox = [];
let newUserIds = {};
let newUsersArr = []; // Make unique
axios.all([
axios.get('/updateUserList'),
axios.get('/userInformation')
])
.then(axios.spread((newUsers, currentUsers) => { // Was shadowed here
userBox.push(newUsers.data)
newUserBox.push(currentUsers.data)
for (let newUser of newUserBox){
newUserIds[newUser.id] = newUser.id
}
for (let user of userBox){
if(!newUserIds[user.staffID]){
console.log(user)
newUsersArr.push(user)
}
}
})).then(dispatch({
type: FETCH_USERS_TO_ADD,
payload: newUsersArr
}))
}