How to determine if TURN server is being used (WebRTC)? - javascript

I want to gather stats on the number of users having to fallback to TURN servers. Thus is there a way to find if a RTCPeerConnection is using a TURN server instead of "directly" communicating with a remote peer?
I've tried using pc.getStats() but that only gives me an object with a size property.

You want to use getSelectedCandidatePair. This will return the local/remote candidate that is being used. Each candidate will have a type host, srflx, prflx or relay. relay means it is using TURN.
Make sure to check both candidates. It is possible that both pairs are TURN (or maybe just one)

the getStats() result is a Javascript Map object. You can iterate it to find what you need. To get the active candidate pair (and then determine its type) it is best to follow the code from this sample (which works around the quirks of some browsers) and then check whether either the local or remote candidateType is 'relay'.

Related

LaunchDarkly: how to access flag values from `localStorage`

I'm using LaunchDarkly in a web app and am playing around with using the 'localStorage' bootstrap option on initialization.
With this option I clearly see my flags in localStorage and they look to be under a key formed with my clientId and then some long, base64 string - I'm curious if there is a clear pattern I can use to access the flag values in localStorage with getItem or if I'm perhaps completely misinterpreting the use case?
What I tried was adding the optional bootstrap option and then logging out my localStorage to see what key the flag values were being stored in, and they appear to be mapped to a key that includes my LD client ID and then some long, seemingly random string.
What I expected was for my keys to be stored under a key of maybe just my LD client ID or some other, easily found property name.
Thank you for any and all insight!
Best,
Zach
The JavaScript client SDK already caches flags in localstorage for you. When the SDK initializes, the flag values for the context (i.e. user) you provide are pulled and cached in localStorage. From that point on, LaunchDarkly's SDK uses localStorage for getting flag values, speeding up flag evaluations and ensuring that flags can be evaluated in the circumstance where LaunchDarkly is temporarily unavailable. Updates to this localStorage cache are streamed by default (though you an configure this for polling).
My point is, there may be no need for bootstrapping off localStorage. Bootstrapping on the client-side is useful for situations where you are writing these values prior to the response hitting the client's browser (for example, you are writing bootstrapped values at the edge).

Generate a unique id in react that persist

I need to keep a unique identifier for each client using my react app.
doing this will regenerate a random string (what I want) but does this on each refresh which is not what I want
const [id] = useState(Math.random().toString(36).substr(2, 8));
I've found uniqueId() form lodash but I'm afraid the id's won't be unique across multiple clients as it only give a unique Id and increment it at every call (1, 2, 3...)
const [id] = useState(_uniqueId());
Is there some kind of _uniqueId that generates a random string and also persist through page refresh?
I don't think there is a built-in or out-of-the-box solution that generates unique id in react that persist automatically. You have two problems to solve.
How to generate unique id. Which was already solved by using the uuid.
And how to persist it.
There are plenty of storage you can use depend on your need. Here's few of them where you can persist your data assuming you want it to be stored in client side.
LocalStorage
SessionStorage
Cookie
IndexedDB API
FileSystem
Again, it depends on your use case. So, carefully check them out which one fits on your requirement.
Another way to generate a temporary ID that would be the same for the same client, without storing it is to use browser fingerprinting.
For example, you can take user-agent, client timezone, and screen resolution, apply some hash function to them and call it an ID.
There are more advanced ways of fingerprinting that would result in less chance of two different users having the same ID, but it'll never be a 0% chance.
You also might want to use some libraries, such as https://github.com/fingerprintjs/fingerprintjs for this.

MediaTrack detect highest level

I have several audio tracks, which i got from getUserMedia (microphone). Those are being transmitted via WebRTC.
I want to highlight the stream that is active at the moment, but checking the documentation for MediaTrack i cannot find any method to access something that allows me to determine if that object is the most active at the moment.
So, if there is a method to get the current output, with some filter i should be able to determine which one is the "most active" one and highlight it.
Does such method exist in the API? Is there another approach that i can take for that?
MediaStream Object has APIs refer to detect active stream but not its MediaStreamTrack.
Even if you want to detect active speaker via volume level you need to pass MediaStream to Web audio API - AudioContext to analyse it. example
If you have proper RTCPeerConnection then you can use getStats API. example
MediaStreamTrack doesn't have such a property. You can use the webaudio api as done by hark to get a volume indication and then determine who is speaking.
Your mileage may vary though, active speaker detection is a hard problem.

Serialize object through network with Javascript - How to improve it?

I have a class Message which can be serialized when the data goes through the network, I currently use JSON, mostly because I use JSON for everything. (webservice, sockets).
I want to improve the serialization to make it as good as possible, I believe improvments are possible here.
The aim is to make the transport string lighter, especially when used by sockets (video game), because it will be used for everything, every response client/server or server/client and even inside the server or client methods, it's the usual way to provide data.
The Message is a complex object that can also contain other object instances, like a MessageLang, which will be responsable to translate a sentence on the client based on a code.
So far it works fine, here are the results:
Socket server emit with simple string:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["Respond to emitter"]}
Socket server emit with simple message instance:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["{\"m\":\"Respond to all clients\",\"d\":{},\"s\":1,\"t\":\"m\"}"]}
Socket server emit with complex message instance:
verbose: websocket writing 5:::{"name":"user.newAuthenticated","args":["{\"m\":{\"m\":\"__12\",\"a\":{\"field\":\"name\",\"min\":3,\"max\":20}},\"d\":{\"key\":\"fakeKey\"},\"s\":1,\"t\":\"m\"}"]}
The complexe message would render the following sentence:
The min length of name is 3. Max length is 20. and would contain the key: "fakeKey" in data. Just to explain how it works.
As you see, the message get bigger and bigger and it is normal, but I would like to know what I can do to make a better serialization here:
Delete the message itself when there aren't (empty)
Delete the data when it's empty as well
Delete the status when it's false (because it's the default value)
I see a lot of \ in the socket log because it is JSON, I believe that's a problem, because each time I'll add something I'll get extra characters that I do not want. Maybe the JSON isn't a good choice and I should serialize differently, first in JSON like the examples at the top, but then in something else, maybe kind of binary, if it takes less space.
What do you think?
And if it would be a good idea to encrypt somehow the message in another format, would the cost of the encryption be worth it? Because encrypt it would take a bit of time as well, so I'm just wondering if it wouldn't just move the issue, like it would take less time to send the message through socket because it would be lighter, but we would use more time to encrypt it. Just wondering.
My guess is that your message object has two fields (name and args).
The first stop to reduce the length of the message is to get rid of the (pretty useless) outer object and replace it with an array. So an empty message
{"name":"empty","args":[]}
would become
["empty",[]]
or even
["empty"]
The next thing is that you have a bug in the serialization of the arguments. Instead of sending JSON, you wrap the JSON data in a string. Example: In the authenticated case, you send
{"name":"user.newAuthenticated","args":["{\"m\":\"Respond to all clients\",\"d\":{},\"s\":1,\"t\":\"m\"}"]}
but you should send
{"name":"user.newAuthenticated","args":[{"m":"Respond to all clients","d":{},"s":1,"t":"m"}]}
instead. Now the question is whether args is a list of a single object. If it's always a single object, then you could get rid of the [] as well. With my suggested change from above, that would give you:
["user.newAuthenticated",{"m":"Respond to all clients","d":{},"s":1,"t":"m"}]
which is pretty good IMO. If you can make the (de-)serializer handle default values properly, you can reduce this to:
["user.newAuthenticated",{"m":"Respond to all clients","s":1,"t":"m"}]
(i.e. we can omit the empty d property).
For a MMO, I think a minimum of data must be sent to the client. If a socket is called 2xx/3xx by sec, you must reduce the size of the data sent through the socket as most as possible.
On another hand, it also consummes resource to encrypt the object on the server side to send a minified version of the object... Wouldn't it be better not to reduce it and to send an object not reduced so we don't spent resource to encrypt it?

Parameter passing vs local storage

I have a lobby written in HTML5 / javascript. A .json file provides a few config parameters for the lobby and for the various other HTML5 games that can be launched from it. These parameters can either be passed to the games in the window.open string ( in the form of:
window.open(http://www.myLovelyDomain.com/index.html?username=bob&token=aaaXXX")
or could be held in localStorage and accessed by the game following it's launch.
My question is, what is the best (most secure/likely to cause least errors/etc) method? I know users can turn off localStorage, but I don't know how many do. Any thoughts?
Advantages of localStorage over URL query strings
Less likely to be user edited
Less likely to be copy&pasted to someone else
Can persist across sessions
Wider choice of characters
(Marginally) less bandwidth usage (shorter GETs)
Can store whole files
Invisible to basic user
Disadvantages
Server doesn't get access to the variables without additional ajax
May be harder to debug
May need extra checks if things change every session (or consider sessionStorage)
Not supported by old browsers
Can't use cross-domain directly (may be advantage, depending on how you look at it)
For supported list and max sizes see here.

Categories