API communication in js web worker - javascript

I have a problem with my code:
I'm using RecorderJS, and I'm trying to permise this to send sound to my back-end, but as streaming, not as complete recording.
I'm using HTML 5 and the last versions of python and flask.
I found where I had to put my code for doing that, but my problem is the communication beetween my back and my worker.
I tried to use XMLHttpRequest :
function send_buffer_to_transcription(sound_buffer) {
// no jquery in workers
var request = new XMLHttpRequest();
var url = "'/updateSound2'";
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log("son transmis");
}
};
var data = {
audioBuffer:JSON.stringify(Array(new Int16Array(sound_buffer)))
}
request.send(data);
}
But I had an issue with that :
Uncaught DOMException: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
at send_buffer_to_transcription (blob:http://127.0.0.1:5000/feb04c56-4e80-4418-885f-5f24bc7b9409:79:23)
at streaming_record (blob:http://127.0.0.1:5000/feb04c56-4e80-4418-885f-5f24bc7b9409:62:19)
at record (blob:http://127.0.0.1:5000/feb04c56-4e80-4418-885f-5f24bc7b9409:101:17)
at self.onmessage (blob:http://127.0.0.1:5000/feb04c56-4e80-4418-885f-5f24bc7b9409:27:25)
I tried with webSocket too :
let socket = new WebSocket("wss://127.0.0.1:5000/soudtesting");
socket.onerror = function (error) {
console.error(error);
}
function send_as_socket() {
socket.send('my message');
}
But here is the issue I've had :
7fdd8dd0-6354-467b-8b58-253c98412fdd:10 WebSocket connection to 'wss://127.0.0.1:5000/soudtesting' failed:
(nothing next)
the error looks :
isTrusted: true
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: 'wss://127.0.0.1:5000/soudtesting', readyState: 3, bufferedAmount: 0, onopen: null, onerror: ƒ, …}
defaultPrevented: false
eventPhase: 0
path: []
returnValue: true
srcElement: WebSocket {url: 'wss://127.0.0.1:5000/soudtesting', readyState: 3, bufferedAmount: 0, onopen: null, onerror: ƒ, …}
target: WebSocket {url: 'wss://127.0.0.1:5000/soudtesting', readyState: 3, bufferedAmount: 0, onopen: null, onerror: ƒ, …}
timeStamp: 0
type: "error"
[[Prototype]]: Event
Does someone has an explaination, and, if possible a solution please? Really needed.
=====
Oops, I forget this :
Here's the error which has occured in my back-end (I don't think this will be helpfull, but why not)
127.0.0.1 - - [06/Apr/2022 13:51:55] code 400, message Bad request version ('úú\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93êê\x00\x00\x00\x17\x00\x00ÿ\x01\x00\x01\x00\x00')
ax°×¥¡²DüöàO»Ëgïò&åf# úúÀ+À/À,À0̨̩ÀÀ / 5 êê ÿ " HTTPStatus.BAD_REQUEST -
127.0.0.1 - - [06/Apr/2022 13:51:55] code 400, message Bad request version ('êê\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93úú\x00\x00\x00\x17\x00\x00ÿ\x01\x00\x01\x00\x00')
èbÄÍdµÜQýH³¾²§¶E|}½eO ËX|Da¼j»-ÃñUxù©í弪v[` êêÀ+À/À,À0̨̩ÀÀ / 5 úú ÿ " HTTPStatus.BAD_REQUEST -

Related

Bad Request error when trying to refresh Django login access token

Trying to refresh the access token I receive from Django every few seconds, however I am getting the error message
Request Method: POST Status Code: 400 Bad Request
I am sending my refresh token to this endpoint: "http://127.0.0.1:8000/api/token/refresh/"
This is my urls.py:
from rest_framework_simplejwt.views import (TokenObtainPairView, TokenRefreshView, TokenVerifyView)
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
urlpatterns = [
path('', include(router.urls)),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
# path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
path('api/register', RegisterApi.as_view()),
]
This is how I am sending my refresh token:
let updateToken = async ()=> {
try {
let response = await axios.post('http://127.0.0.1:8000/api/token/refresh/',JSON.stringify(authTokens.refresh))
//update state with token
setAuthTokens(authTokens => ({
...response.data
}))
//update user state
const decoded = jwt_decode(response.data.access)
setUser(user => ({
...decoded
}))
//store tokens in localStorage
//we stringify because we can only store strings in localStorage
localStorage.setItem('authTokens',JSON.stringify(response.data))
}
catch(err) {
//if fail, something is wrong with refresh token
console.log(err.response)
}
}
This is the error I am getting:
config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data:
refresh: ['This field is required.']
[[Prototype]]: Object
headers:
content-length: "39"
content-type: "application/json"
[[Prototype]]: Object
request: XMLHttpRequest
onabort: ƒ handleAbort()
onerror: ƒ handleError()
onload: null
onloadend: ƒ onloadend()
onloadstart: null
onprogress: null
onreadystatechange: null
ontimeout: ƒ handleTimeout()
readyState: 4
response: "{\"refresh\":[\"This field is required.\"]}"
responseText: "{\"refresh\":[\"This field is required.\"]}"
responseType: ""
responseURL: "http://127.0.0.1:8000/api/token/refresh/"
responseXML: null
status: 400
statusText: "Bad Request"
timeout: 0
upload: XMLHttpRequestUpload {onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, …}
withCredentials: false
[[Prototype]]: XMLHttpRequest
status: 400
statusText: "Bad Request"
[[Prototype]]: Object
This is what i have in authTokens:
{refresh: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90e…9tIn0._aS9oDcj3Rfomodbs9qMEFmgEm4oEdOfSwGSJJKLWmg', access: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90e…20ifQ.K1YCXWoMWF7o61fGAuVm-QoehB3-jA2A_dLZ4o4uYa8'}
The /api/token/refresh/ returns only the access token.
When you setAuthToken using the entire response data, you are most likely getting rid of the refresh token.
Now the next time you make the request, authTokens.refresh is undefined and thus does not get sent to the backend. The backend rightfully complains that it's a 400: Bad Request. refresh is a required field.
Modify your frontend code to only update the access token. When the refresh token expires, you need to call /api/token/ to login again.
Alternatively you can change the backend to rotate refresh tokens. This would send a new refresh token each time the access token is refreshed.
This is achieve by setting ROTATE_REFRESH_TOKENS = True in your settings.
If you want to make sure the old refresh token can no longer be used, you can blacklist them when rotated, by setting BLACKLIST_AFTER_ROTATION = True

How can I read WebSocket data and convert it to JSON format (Blob to JSON) from Kite Connect?

Preface: I am new to websockets
I am able to open, close and receive messages once I connect to the WebSocket but I have no idea how to read the incoming data.
The message I receive looks like the following:
MessageEvent {isTrusted: true, data: Blob, origin: "wss://ws.kite.trade", lastEventId: "", source: null, …}
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
data: Blob {size: 48, type: ""}
defaultPrevented: false
eventPhase: 0
isTrusted: true
lastEventId: ""
origin: "wss://ws.kite.trade"
path: []
ports: []
returnValue: true
source: null
srcElement: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxxxxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
target: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxxxxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
timeStamp: 74468.20000000298
type: "message"
userActivation: null
the e.data looks like:
Blob {size: 48, type: ""}
size: 48
type: ""
[[Prototype]]: Blob
arrayBuffer: ƒ arrayBuffer()
size: (...)
slice: ƒ slice()
stream: ƒ stream()
text: ƒ text()
type: (...)
constructor: ƒ Blob()
Symbol(Symbol.toStringTag): "Blob"
get size: ƒ size()
get type: ƒ type()
Here is what I have done so far, in my React App:
CodeSandbox
import { useEffect, useRef } from "react";
import { Typography } from "#material-ui/core";
const DUMMY_HOLDINGS = [
{
tradingsymbol: "IRFC",
instrument_token: 519425,
last_price: 23.45
},
{
tradingsymbol: "M&M",
instrument_token: 519937,
last_price: 755
},
{
tradingsymbol: "SINTEXPLAST",
instrument_token: 138407172,
last_price: 5.65
},
{
tradingsymbol: "ZOMATO",
instrument_token: 1304833,
last_price: 138.7
},
{
tradingsymbol: "ZYDUSWELL",
instrument_token: 136021764,
last_price: 2170
}
];
const SomeComponent = (props) => {
const ACCESS_TOKEN = `xxxxxxxxxxxxxxxxx`; //redacted for obvious reasons
const API_KEY = `xxxxxxxxxx`; //redacted for obvious reasons
const ws_url = `wss://ws.kite.trade?api_key=${API_KEY}&access_token=${ACCESS_TOKEN}`;
console.log(`WebSocket URL is: `, ws_url);
const ws = useRef(null); // as a pointer to the websocket connection
// The first useEffect gets the holdings if there are none, and
// then creates a websocket connection
useEffect(() => {
// creates a new WebSocket
ws.current = new WebSocket(ws_url);
// the websocket requries one to "subscribe" to the instruments one wants
// live data for, for each instrument it requires it's instrument_token
// extracted from the DUMMY_ARRAY
// refer to the docs for more info: https://kite.trade/docs/connect/v3/websocket/#request-structure
const holdingInTokenArray = DUMMY_HOLDINGS.map(
(holding) => holding.instrument_token
);
const message = { a: "subscribe", v: holdingInTokenArray };
// Once the WS connection opens we send the request for the instruments subscribed as per the
// docs in the message above
ws.current.onopen = () => {
console.log(`ws opened for ALL DUMMY_HOLDINGS`);
console.log(message);
ws.current.send(JSON.stringify(message));
};
ws.current.onclose = () => console.log(`ws closed for ALL DUMMY_HOLDINGS`);
// Quick refresher: the useEffect return statement below runs before the useEffect hook, EXCEPT
// EXCEPT for
// 1. upon first render
// 2. upon removal of DOM component
return () => {
ws.current.close();
};
}, [ws_url]);
// This useEffect is for handling the onmessage WS event.
// THIS IS WHERE MY PROBLEM BEGINS...
useEffect(() => {
// Simple guard statement
if (!ws.current) return;
// the onmessage event fires as expected, I just don't know how to read the e.data
// which is supposed to contain the data I am looking for. I've read the docs
// https://kite.trade/docs/connect/v3/websocket/#binary-market-data
// tried .text() .arrayBuffer() but I can't make sense of the results.
// My think my confusion is rooted in not knowing how to read Blob Data and converting
// Blob into a format like the docs. Even if I just get an array of the Binary Data like
// the docs I can handle it from there, I just don't know how to
ws.current.onmessage = async (e) => {
console.log(e.data);
/**
* e.data logs the following
MessageEvent {isTrusted: true, data: Blob, origin: "wss://ws.kite.trade", lastEventId: "", source: null, …}
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
data: Blob {size: 48, type: ""}
defaultPrevented: false
eventPhase: 0
isTrusted: true
lastEventId: ""
origin: "wss://ws.kite.trade"
path: []
ports: []
returnValue: true
source: null
srcElement: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxxxxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
target: WebSocket {url: "wss://ws.kite.trade/?api_key=xxxxx&access_token=xxxxxxxx", readyState: 3, bufferedAmount: 0, onerror: null, onopen: ƒ, …}
timeStamp: 74468.20000000298
type: "message"
userActivation: null
*/
console.log(await e.data.text());
const message = JSON.parse(e.data);
console.log("e: ", message);
};
}, []);
// Once I am able to read the returned WS data, I want to populate some of it below for each of the
// instruments.
return (
<>
{!DUMMY_HOLDINGS.length ? (
<Typography>No Holdings Found</Typography>
) : (
DUMMY_HOLDINGS.map((item) => {
return (
<div style={{ "box-shadow": "0 4px 8px 0 rgba(0,0,0,0.2)" }}>
<h3>
Stock : {item.tradingsymbol} ({item.instrument_token})
</h3>
<p>Last Price: {item.last_price}</p>
</div>
);
})
)}
</>
);
};
export default SomeComponent;
I just don't understand how to extract the data from binary to something I know what to do with. I've scratched my head endlessly on this for a while now, I think it would be easy for someone with experience in websockets, please help! 🥺🙏
first convert Blob data recieved in the e.data response to an ArrayBuffer using
let t1 = await blob.arrayBuffer()
const a1 = new DataView(t1.slice(0,2)).getInt16() // number of packets
const b1 = new DataView(t1.slice(2,4)).getInt16() // bytes in packet
const c1_instrument_token = new DataView(t1.slice(4,8)).getInt32() // instrument token of packet 1
const c1_ltp = new DataView(t1.slice(8,12)).getInt32() // ltp of packet 1
and so on the key is to use the DataView to extract the underlying values. I swear my future self is going to forget I knew this and read this at some point and thank my past self. Hope this helps someone else also
const text = await (new Response(e.data)).text();

Http provider doesn't reach my localhost server

I've got a provider that uses the Http service to perform a GET operation over a localhost server:
requestAchievedCombined(config){
return new Promise( (resolve, reject) => {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
this.http.get(URL+"/api"+query).subscribe( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
resolve(response);
}, err => this.errorHandler(err, reject));
})
}
The server is hosted in localhost:3000 and running, and it works perfectly when called from the navigator with that same GET query string... it returns some JSON.
Thing is, when I execute my Angular app, this gives me the following error:
ERROR [DataRequester] =>
{…}
_body: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api</pre>\n</body>\n</html>\n"
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 404
statusText: "Not Found"
type: 2
url: "http://localhost:4200/function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api?collection=achieved_combined&query=columns"
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
Do anybody know why this happens? What am I doing wrong? I'm using the latest Angular version.
pd: yes I tried putting http:// before localhost in the URL.
EDIT: After changing the url to http://localhost:3000 and call the property in a proper way (I was forgetting the this. thing), I could manage to communicate with the server, but now I'm having this issue:
ERROR [DataRequester] =>
{…}
_body: error
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: null
defaultPrevented: false
eventPhase: 0
explicitOriginalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
isTrusted: true
lengthComputable: false
loaded: 0
originalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
target: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
timeStamp: 3687.8557595446277
total: 0
type: "error"
__proto__: ProgressEventPrototype { lengthComputable: Getter, loaded: Getter, total: Getter, … }
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 0
statusText: ""
type: 3
url: null
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
URL is a global function that gets "called". Try renaming the URL var to url and it should work.
Okay, first thing wrong was that I wasn't calling the URL property in a good way: actually, it wasn't in the method but in the class, and I was forgetting the "this.", so I wasn't pointing to the right variable.
Secondly, fixed my edit simply setting up CORS in my express server:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Now my Angular app correctly gets the data!
I'm just passing by to give you some code
requestAchievedCombined(config): Observable<any> {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
return this.http.get(URL+"/api"+query)
.map( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
return response;
}, err => this.errorHandler(err))
// .toPromise() // If you still want your cherished promise
;
}
I've changed your function to simplify it : you should use Observables instead of Promises. I know, I was skeptical at first too, but Observables are way more powerful than promises. and if you still don't like it, simply call .toPromise() right after the map operator, it will still be clearer ;)
Other than that, Could you post the trace of your error instead of the payload ? We need the error message to know what is happening.

RTCDataChannel ready state stuck at connecting in chrome but working in Firefox

I am trying to implement RTCDataChannel(webRTC).
It's working good in Firefox but not in chrome.
Both Chrome and Firefox are of the latest version.
RTCDataChannel object in Chrome :-
RTCDataChannel {
binaryType: "arraybuffer"
bufferedAmount: 0
bufferedAmountLowThreshold: 0
id: 65535
label: "sendDataChannel"
maxRetransmitTime: 65535
maxRetransmits: 65535
negotiated: false
onbufferedamountlow: null
onclose: null
onerror: ƒ (event)
onmessage: ƒ (event)
onopen: ƒ dataChannelStateChanged()
ordered: true
protocol: ""
readyState: "connecting"
reliable: false__proto__:}
RTCDataChannel object in Firefox :-
DataChannel {
binaryType: "blob"
id: 0
label: "sendDataChannel",
reliable: true,
readyState: "open",
bufferedAmount: 0,
bufferedAmountLowThreshold: 0,
onopen: dataChannelStateChanged(),
onerror: create_peer_connection/dataChannel.onerror(),
onclose: null,
onmessage: create_peer_connection/dataChannel.onmessage(),
onbufferedamountlow: null
protocol:""
ordered:true}
I have already gone through below links:-
WebRTC data channel stack on readyState "conecting"
WebRTC dataChannel.readyState stalling on "connecting"
RTCDataChannel's ReadyState is not 'open'.
Webrtc Data Channel always in connecting state and not open
Please suggest what could be the reason behind the issue in chrome?
I was able to resolve it using the following post :
WebRTC DataChannel: working in Firefox but not Chrome
I had to change
pc = new RTCPeerConnection(configuration,
{optional: [{RtpDataChannels: true}]});
to
pc = new RTCPeerConnection(configuration);

Websocket SSL connection

I am trying to test a secure websocket but I'm having trouble. Here is my test:
var WebSocket = require('ws');
describe('testing Web Socket', function() {
it('should do stuff', function(done) {
var ws = new WebSocket('wss://localhost:15449/', {
protocolVersion: 8,
origin: 'https://localhost:15449'
});
ws.on('open', function() {
console.log('open!!!');
done();
});
console.log(ws);
});
});
Here's the log of "ws" after it's created:
{ domain: null,
_events: { open: [Function] },
_maxListeners: undefined,
_socket: null,
_ultron: null,
_closeReceived: false,
bytesReceived: 0,
readyState: 0,
supports: { binary: true },
extensions: {},
_isServer: false,
url: 'wss://localhost:15449/',
protocolVersion: 8 }
I don't get a log back from open. I am running the project locally and when I use the Chrome Advanced Rest Client tool I am able to connect just fine.
Am I missing something? Please help.
Edit:
I added ws.on('error') and it logged out { [Error: self signed certificate] code: 'DEPTH_ZERO_SELF_SIGNED_CERT' }
I've also tried following this code but get the same error.
The https module is rejecting your self-signed cert (as one would hope). You can force it to stop checking by passing a rejectUnauthorized: false option (which WebSocket will pass down to https):
var ws = new WebSocket('wss://localhost:15449/', {
protocolVersion: 8,
origin: 'https://localhost:15449',
rejectUnauthorized: false
});

Categories