How would you be able to achieve real-time video with Websocket? - websocket

Suppose I have this web application client that connects/subscribes to a Websocket server. In which this websocket server sends the binary sent from clients to subscribers.
The client sends chucks of webm recorded video (e.g. every 1 second) then the server sends those chucks to every client to display the video stream.
My issue here is when the network slows down then the sending of the "buffer" webm will pile up and a noticeable lag will be displayed. So if there's a connection problem for 15 seconds, then there will be this 15 chucks to send then the WebSocket server will just broadcast those chucks to subscribers causing those clients to playback a stream that is 15 seconds in the past, so this become totally not real-time.
What is the general approach to be able to achieve real-time video with Websocket?
ps. I understand there's WebRTC, but in my case, I have to use Websocket.

Related

Would broadcasting video to multiple Socket.IO servers using the Redis Adapter work and be fast enough?

The socket.io section on broadcasting events with multiple Socket.IO servers says:
Broadcasting also works with multiple Socket.IO servers.
You just need to replace the default adapter by the Redis Adapter or another compatible adapter.
I am going through system design interview practice. I found a question about supporting livestream of a video from one producer to one consumer. I then needed to discuss how to scale this up to 10,000 consumers and then 1,000,000 consumers.
Would using broadcasting events with multiple Socket.IO servers work and be fast enough?
To support 1,000,000 consumers, I suggested having 100 machines each support the 1,000 consumers' 1,000 web socket connections. Each machine that has a consumer subscribed to the livestreamer would add the socket to a room associated with the producer.
When the producer livestreams video through its web socket connection, the video would be routed by the load balancer to the Socket.IO server, which would broadcast the video to room using the Redis Adapter (which does pub-sub).
I know WebRTC can be used for this, but if I have a lot of clients consuming the video, then I think web sockets are a better fit.
Would this work? Would this be real-time enough for a livestream?
How many machines could this scale to before it would be too slow?

How can I send js mediaStream to server and return the processed stream?

I want to send live webcam stream from website to my server, and the server will do some processing on the frames and return the processed stream. I'm thinking about using WebRTC to send live stream to server (server as a peer), and return the processed frames by images via WebSocket. Is there any easier way to do this?
WebRTC.getUserMedia can capture video stream, but you cannot send them to your server.(you can do this if your server can parse them to a complete picture)
So the easier way to finish this problem is that post the picture which captured by webrtc.getUserMedia to server, and then your server return the processed picture. You can use canvas to show those pictures.
You can read this Computer Vision on the Web with WebRTC and TensorFlow

Is it possible to emit stream object through socket.io

For my app I'm streaming audio data from a raspberry-pi client to my node.js audio service through socket.io. The problem is, to process the audio, I'm piping the audio stream from client in my service to an external service. Then this external service will give the result stream audio back to my service and my service will emit it to the client.
So my application flow is like
Client ---socket.io-stream---> audio_service ---stream---> external_service
external_service --stream---> audio_service ---socket.io-stream---> client
My questions is:
Is it possible that when a client connected to my audio_service, my audio_service will initiate a connection to external_service and emit that connection back to the client through socket.io? This way the client will stream audio directly to the external_service by using the returned connection instead of going through audio_service.
If it is possible, is it also possible that even though the client stream audio directly to the external_service, it will still send the stream result back to the audio_service?
Thank you very much for your help
It isn't possible to send a stream through Socket.IO the way it is set up today. Some folks have made some add-ons that emulate streams in the usual evented RPC way, but it isn't very efficient.
The best library I know for this is Binary.JS. This will give you streams multiplexed over a single binary WebSocket connection. Unfortunately, Binary.js hasn't been maintained in awhile, but it still works.

How to trigger websocket frame fragmentation from the client?

I'm building a Web socket server, however, for testing purposes, I'd like Chrome or Firefox or any other browser to send the message fragmented so I can test my implementation.
I've tried even sending 100K text data and the FIN flag is always set to 1 and the opcode is TEXT.
Is there a way to manually trigger fragmented frames? Any client out there with more flexibility?
The Javascript WebSocket API does not expose this option. I recently ran into the same frustration when some more modern browsers (A Chromium derivative) was unpredictably sending fragmented WebSocket frames.
For testing I rolled my own TCP client sending pre-calculated fragmented WebSocket frames. Not ideal, but it got the job done, and AFAIK there's no alternative yet.

WebSockets, UDP, and benchmarks

HTML5 websockets currently use a form of TCP communication. However, for real-time games, TCP just won't cut it (and is great reason to use some other platform, like native). As I probably need UDP to continue a project, I'd like to know if the specs for HTML6 or whatever will support UDP?
Also, are there any reliable benchmarks for WebSockets that would compare the WS protocol to a low-level, direct socket protocol?
On a LAN, you can get Round-trip times for messages over WebSocket of 200 microsec (from browser JS to WebSocket server and back), which is similar to raw ICMP pings. On MAN, it's around 10ms, WAN (over residential ADSL to server in same country) around 30ms, and so on up to around 120-200ms via 3.5G. The point is: WebSocket does add virtually no latency to the one you will get anyway, based on the network.
The wire level overhead of WebSocket (compared to raw TCP) is between 2 octets (unmasked payload of length < 126 octets) and 14 octets (masked payload of length > 64k) per message (the former numbers assume the message is not fragmented into multiple WebSocket frames). Very low.
For a more detailed analysis of WebSocket wire-level overhead, please see this blog post - this includes analysis covering layers beyond WebSocket also.
More so: with a WebSocket implementation capable of streaming processing, you can (after the initial WebSocket handshake), start a single WebSocket message and frame in each direction and then send up to 2^63 octets with no overhead at all. Essentially this renders WebSocket a fancy prelude for raw TCP. Caveat: intermediaries may fragment the traffic at their own decision. However, if you run WSS (that is secure WS = TLS), no intermediaries can interfere, and there you are: raw TCP, with a HTTP compatible prelude (WS handshake).
WebRTC uses RTP (= UDP based) for media transport but needs a signaling channel in addition (which can be WebSocket i.e.). RTP is optimized for loss-tolerant real-time media transport. "Real-time games" often means transferring not media, but things like player positions. WebSocket will work for that.
Note: WebRTC transport can be over RTP or secured when over SRTP. See "RTP profiles" here.
I would recommend developing your game using WebSockets on a local wired network and then moving to the WebRTC Data Channel API once it is available. As #oberstet correctly notes, WebSocket average latencies are basically equivalent to raw TCP or UDP, especially on a local network, so it should be fine for you development phase. The WebRTC Data Channel API is designed to be very similar to WebSockets (once the connection is established) so it should be fairly simple to integrate once it is widely available.
Your question implies that UDP is probably what you want for a low latency game and there is truth to that. You may be aware of this already since you are writing a game, but for those that aren't, here is a quick primer on TCP vs UDP for real-time games:
TCP is an in-order, reliable transport mechanism and UDP is best-effort. TCP will deliver all the data that is sent and in the order that it was sent. UDP packets are sent as they arrive, may be out of order, and may have gaps (on a congested network, UDP packets are dropped before TCP packets). TCP sounds like a big improvement, and it is for most types of network traffic, but those features come at a cost: a delayed or dropped packet causes all the following packets to be delayed as well (to guarantee in-order delivery).
Real-time games generally can't tolerate the type of delays that can result from TCP sockets so they use UDP for most of the game traffic and have mechanisms to deal with dropped and out-of-order data (e.g. adding sequence numbers to the payload data). It's not such a big deal if you miss one position update of the enemy player because a couple of milliseconds later you will receive another position update (and probably won't even notice). But if you don't get position updates for 500ms and then suddenly get them all out once, that results in terrible game play.
All that said, on a local wired network, packets are almost never delayed or dropped and so TCP is perfectly fine as an initial development target. Once the WebRTC Data Channel API is available then you might consider moving to that. The current proposal has configurable reliability based on retries or timers.
Here are some references:
WebRTC Introduction
WebRTC FAQ
WebRTC Data Channel Proposal
To make a long story short, if you want to use TCP for multiplayer games, you need to use what we call adaptive streaming techniques. In other words, you need to make sure that the amount of real-time data sent to synchronize the game world among the clients is governed by the currently available bandwidth and latency for each client.
Dynamic throttling, conflation, delta delivery, and other mechanisms are adaptive streaming techniques, which don't magically make TCP as efficient as UDP, but make it usable enough for several types of games.
I tried to explain these techniques in an article: Optimizing Multiplayer 3D Game Synchronization Over the Web (http://blog.lightstreamer.com/2013/10/optimizing-multiplayer-3d-game.html).
I also gave a talk on this topic last month at HTML5 Developer Conference in San Francisco. The video has just been made available on YouTube: http://www.youtube.com/watch?v=cSEx3mhsoHg
There's no UDP support for Websockets (there really should be), however you can apparently use WebRTC's RTCDataChannel API for UDP-like communication. There's a good article here:
http://www.html5rocks.com/en/tutorials/webrtc/datachannels/
RTCDataChannel actually uses SCTP which has configurable reliability and ordered delivery. You can get it to act like UDP by telling it to deliver messages unordered, and setting the maximum number of retransmits to 0.
I haven't tried any of this though.
I'd like to know if the specs for HTML6 or whatever will support UDP?
WebSockets won't. One of the benefits of WebSockets is that it piggybacks the existing HTTP connection. This means that to proxies and firewalls WebSockets looks like HTTP so they don't get blocked.
It's likely arbitrary UDP connections will never be part of any web specification because of security concerns. The closest thing to what you're after will likely come as part of WebRTC and it's associated JSEP protocol.
are there any reliable benchmarks ... that .. compare the WS protocol to a low-level, direct socket protocol?
Not that I'm aware of. I'm going to go out on a limb and predict WebSockets will be slower ;)

Resources