04/16/2017 at 18:52 •
This is a very quick and easy article explaining how to stream movies to an HTML 5 video tag using NodeJS. The whole project is very small and compact. The
video.jsfile is where you should focus your attention. The file is in the
But first, what are streams?
If you never dealt with streams, you might think to yourself, why not just link the movie file straight to the video tag? If we do that, the whole movie file might be loaded into memory on the server side. Now you may be thinking, but this file is just 30MB in size, so what is the problem?
Well, imagine that you have 16GB of RAM on the server, but you have a 20GB video file on the drive. What now? How would you load such a massive file that exceeds the RAM capacity? Streams are the answer 😎.
With streams, you have your file on disk, sitting there and having a good time. By using the .createReadStream() method, and telling it which part of the file you're interested in, you will just get a chunk of the whole thing. For example, just 1MB. Then you take that 1MB, send it to whoever requested it, and you're done.
If you are interested in learninig more about Streams, check out this other article that I wrote, titled: How-to-Understand-Streams-in-NodeJS.
The high level code explanation
As you can see from the code, the front end part of the project is super basic. The only thing that matters is the HTML 5 video tag and his URL to the resource of the video. Which, in this case, is a URL to a NodeJS
- Checks the request to see how much data the video tag requested
- Opens the movie file as a stream
- Reads the requested chunks
- Sends back the data with the response
And this is it. The video tag will keep making requests to the provided URL until it gets the whole movie. The only job for your code is to keep reading parts of the file that the tag asks for.
What this project is not
This article is not a full implementation of the HTTP/1.1 Range Requests standard, meaning that there are edge cases that are not taken into consideration. This document is intended to be a good starting point to help you better understand the basics of this technology.
Once you deploy the server on Heroku, you will see the video player in the middle of the page, and you should see the player buffering up with the trailer of Toy Story, which is included in this repo. Replace the movie with another one, but keep in mind that the format of the video must be compatible with what the video tag in your browser is capable of.
If you've enjoyed this article/project, please consider giving it a 🌟. Also check out my GitHub account, where I have other articles and apps that you might find interesting.
Where to follow
You can follow me on social media 🐙😇, at the following locations:
More about me
I don’t only live on GitHub, I try to do many things not to get bored 🙃. To learn more about me, you can visit the following links:
04/16/2017 at 18:51 •
I’m David, and my goal with this repository/article is to demystify Sockets by try to explain them in the simplest possible way.
In these examples, I’m going to use NodeJS and Particle (any version will do) to show how hardware can talk with NodeJS, and vice versa. But make no mistake, this doesn’t mean the tools that I choose are the only way to go about this. This is what I personally know.
Any embedded device with network connectivity will work similarly, and any language with sockets support will also do.
The Repo Structure
- Sockets folder: Here you can find the simplest form of sockets examples. Files in this folder should help you understand how to use TCP, UDP, and TLS (NodeJS only for now). These are basically templates.
- Examples folder: Here you will find specific examples that provide more of a working solution for a specific problem.
- NodeJS2Hardware: Using NodeJS to control an LED.
- Hardware2NodeJS: Read values from an analog PIN, and stream the data to NodeJS. This example also explains how to send data as chars or binary.
- BetterTCPStreamHandling: NodeJS buffers the received data until the END character is detected.
- StaticPage: Learn how to turn your Particle into a web server.
- DynamicPages: Learn how to turn your Particle into a web server with multiple pages.
- DynamicContent: Learn how to turn your Particle in to a web server with dynamic content.
The End Goal
I believe there is a large measure of mystery around sockets. Many people have made them sound scary over the years, and my goal is to prove that they aren’t that mysterious or complicated. I hope that in the end you are going to think about sockets as a simpler solution to a specific problem.
Especially in embedded systems, where every byte counts.
What are Sockets
Sockets are the foundation for all network connectivity. Every connected device uses sockets. On top of sockets, you'll have protocols, which are nothing other than rules that specify how data should be sent or processed after it's received. The popular HTTP protocol is an example of this. Knowing this, you can mimic any device with any language that has Socket support. How? By sending bytes that adhere to specific protocols (rules). These rules are freely available online.
You could make an app that pretends to be a:
Why do people believe Sockets are complicated?
Probably because people tend to use words that convey complexity, like:
- I’m crafting packets.
- It is the lowest software layer.
- I just sent the right amount of bytes.
- I’m implementing this protocol.
Just by reading these few points you might think, This is not for me. But Sockets are actually very straightforward. For example, to get a response from a web server, you just need to send the following text:
GET / HTTP/1.1
This is it. The server will take this text, parse it, and understand that you are making a:
- GET request: You want something from the server.
- /: is the root address of the site. Another example would be to write
/contactto get the contact page.
- HTTP/1.1: Tells the server which HTTP version you can understand.
There isn’t much more to it. A printer will understand another header, similarly a DNS server will need something specific to its protocol (rules).
Hard to believe? Use a telnet app to connect to your favorite site using this command (only an insecure connection will be supported through port 80).
GET / HTTP/1.1
- Press enter twice, and you’ll get the page.
For a secure connection, you can use openssl as follows:
Openssl s_client -connect google.com:443
- Admire all the security that is going on.
GET / HTTP/1.1
- Press enter twice. You’ll get the page.
Another example would be to send an email by connecting straight to a SMTP server. Most current SMTP servers are secured by passwords and use encryption, which makes it hard to quickly test this. But if you had access to a plain SMTP server, you could just type the following:Read more »
04/16/2017 at 18:50 •
I’m David, and my goal with this repository is to demystify the word protocols in enven more detail then my previous article called IoT-Raw-Sockets-Examples, and proving that there is nothing to hard to learn. We just need to pass through the unknown...
Before you start, I recommend that you read the previous article, in which I explain sockets in detail, using Particle and NodeJS. We're going to use sockets in this one, too, but this time, we're going to focus on how to work with a binary protocol. We're also going to craft our own ICMP header, and read the response from the remote host.
I know that the words protocol, binary, and crafting - might sound hard or complicated, but my point is that this is not the case.
How to understand a header specification
If you visit the wikipedia page that covers the ICMP protocol, you’ll find this table that describes the header that needs to be sent over the wire to actually make a Ping request.
Let's start by understanding that we are talking about a binary protocol, meaning we are going to send bytes, which are numbers. Those numbers are as is, they are not an ASCII representation of the keyboard character set - for example.
One byte is 8 bits, which means that an integer of value 8 is
00001000. This is not an ASCII 8, the same letter that you are reading right now. This means that we can’t type just the number 8 on our keyboards and send it out.
Pre flight check
To make our life easier, we're going to write our data in Hex (short for Hexadecimal). This format is way more manageable, because instead of writing numbers as integers, we're going to write an integer in a set of 2 characters. 38450 becomes
0x9632, and we can display this as
96 32(where the
0xis just a way to mark a set of character as Hex), inserting a space every 2 numbers, because 2 numbers in Hex are one byte. This makes it way easier to debug in the console, and read.
Let's break down the table above
It starts with
31, which means each row consists of 32 bits, which, if we divide by 8 bits, gives us 4 bytes. The table has 3 rows, so in total we are going to send 12 bytes.
The first row consists of 3 data sets: 1 byte for the type (uint8_t); 1 byte for the code (uint8_t); and 2 bytes for the check sum (uint16_t). This could look something like this:
08 00 FF F7.
The second row has 2 bytes (uint16_t) for the identifier, and 2 for the sequence number. As an example:
09 A0 00 01.
The third row is the payload, which is optional. You could send some random data, and the router would have to return that data back to you. It's useful if you want to be sure that data is not being lost along the way. But in our example, we are not going to use this option.
Why we're using NodeJS for this project
This project has NodeJS to show the difference between a low level language and a high level one. NodeJS can handle sockets very well. However, there are different types of sockets that live in different parts of the OSI model. As you can see from the Wikipedia table, TCP and UDP lives on the fourth layer of the model, which NodeJS can handle. But from the Examples column, you can see that ICMP lives on the third layer, and NodeJS can’t reach this layer. But we will still be able to ping from NodeJS - how? I’ll explain later.
The file structure
As you can see from the repository, there are two folders: C and NodeJS. Each folder has three files that are named using the same format to help you to easily match each example from one language to the other:
- pingWithBareMinimum: This file will create a PING with the bare minimum code needed to do so, so we can focus on understanding how to build our own header, and get a result from the remote machine.
- pingWithStructResponse: This file is where we are going to apply our knowledge from before. This time, however, we're going to store the result in a C struct, and a buffer in the case of NodeJS
- pingWithChecksum: This is where we implement everything, so we can actually send a proper ping with changing data.
Let's...Read more »