Giter Site home page Giter Site logo

jul0105 / teaching-heigvd-res-2020-labo-orchestra Goto Github PK

View Code? Open in Web Editor NEW

This project forked from softeng-heigvd/teaching-heigvd-res-2020-labo-orchestra

0.0 1.0 0.0 544 KB

UDP lab

Dockerfile 3.19% JavaScript 80.62% Shell 11.55% HTML 4.64%

teaching-heigvd-res-2020-labo-orchestra's Introduction

Teaching-HEIGVD-RES-2020-Labo-Orchestra

Admin

  • You can work in groups of 2 students.
  • It is up to you if you want to fork this repo, or if you prefer to work in a private repo. However, you have to use exactly the same directory structure for the validation procedure to work.
  • We expect that you will have more issues and questions than with other labs (because we have a left some questions open on purpose). Please ask your questions on Telegram / Teams, so that everyone in the class can benefit from the discussion.

Objectives

This lab has 4 objectives:

  • The first objective is to design and implement a simple application protocol on top of UDP. It will be very similar to the protocol presented during the lecture (where thermometers were publishing temperature events in a multicast group and where a station was listening for these events).

  • The second objective is to get familiar with several tools from the JavaScript ecosystem. You will implement two simple Node.js applications. You will also have to search for and use a couple of npm modules (i.e. third-party libraries).

  • The third objective is to continue practicing with Docker. You will have to create 2 Docker images (they will be very similar to the images presented in class). You will then have to run multiple containers based on these images.

  • Last but not least, the fourth objective is to work with a bit less upfront guidance, as compared with previous labs. This time, we do not provide a complete webcast to get you started, because we want you to search for information (this is a very important skill that we will increasingly train). Don't worry, we have prepared a fairly detailed list of tasks that will put you on the right track. If you feel a bit overwhelmed at the beginning, make sure to read this document carefully and to find answers to the questions asked in the tables. You will see that the whole thing will become more and more approachable.

Requirements

In this lab, you will write 2 small NodeJS applications and package them in Docker images:

  • the first app, Musician, simulates someone who plays an instrument in an orchestra. When the app is started, it is assigned an instrument (piano, flute, etc.). As long as it is running, every second it will emit a sound (well... simulate the emission of a sound: we are talking about a communication protocol). Of course, the sound depends on the instrument.

  • the second app, Auditor, simulates someone who listens to the orchestra. This application has two responsibilities. Firstly, it must listen to Musicians and keep track of active musicians. A musician is active if it has played a sound during the last 5 seconds. Secondly, it must make this information available to you. Concretely, this means that it should implement a very simple TCP-based protocol.

image

Instruments and sounds

The following table gives you the mapping between instruments and sounds. Please use exactly the same string values in your code, so that validation procedures can work.

Instrument Sound
piano ti-ta-ti
trumpet pouet
flute trulu
violin gzi-gzi
drum boum-boum

TCP-based protocol to be implemented by the Auditor application

  • The auditor should include a TCP server and accept connection requests on port 2205.
  • After accepting a connection request, the auditor must send a JSON payload containing the list of active musicians, with the following format (it can be a single line, without indentation):
[
  {
  	"uuid" : "aa7d8cb3-a15f-4f06-a0eb-b8feb6244a60",
  	"instrument" : "piano",
  	"activeSince" : "2016-04-27T05:20:50.731Z"
  },
  {
  	"uuid" : "06dbcbeb-c4c8-49ed-ac2a-cd8716cbf2d3",
  	"instrument" : "flute",
  	"activeSince" : "2016-04-27T05:39:03.211Z"
  }
]

What you should be able to do at the end of the lab

You should be able to start an Auditor container with the following command:

$ docker run -d -p 2205:2205 res/auditor

You should be able to connect to your Auditor container over TCP and see that there is no active musician.

$ telnet IP_ADDRESS_THAT_DEPENDS_ON_YOUR_SETUP 2205
[]

You should then be able to start a first Musician container with the following command:

$ docker run -d res/musician piano

After this, you should be able to verify two points. Firstly, if you connect to the TCP interface of your Auditor container, you should see that there is now one active musician (you should receive a JSON array with a single element). Secondly, you should be able to use tcpdump to monitor the UDP datagrams generated by the Musician container.

You should then be able to kill the Musician container, wait 5 seconds and connect to the TCP interface of the Auditor container. You should see that there is now no active musician (empty array).

You should then be able to start several Musician containers with the following commands:

$ docker run -d res/musician piano
$ docker run -d res/musician flute
$ docker run -d res/musician flute
$ docker run -d res/musician drum

When you connect to the TCP interface of the Auditor, you should receive an array of musicians that corresponds to your commands. You should also use tcpdump to monitor the UDP trafic in your system.

Task 1: design the application architecture and protocols

# Topic
Question How can we represent the system in an architecture diagram, which gives information both about the Docker containers, the communication protocols and the commands?
Question Who is going to send UDP datagrams and when?
The musicians will send UDP datagrams each second.
Question Who is going to listen for UDP datagrams and what should happen when a datagram is received?
The auditor will listen to UDP datagrams and will update its internal list of musician when a new datagram is received.
Question What payload should we put in the UDP datagrams?
The musician will send the sound of his instrument of course but he also want to send a unique ID so the auditor can identify him among others musicians with the same instrument
Question What data structures do we need in the UDP sender and receiver? When will we update these data structures? When will we query these data structures?
The receiver will need an array to store every active musician. It will update this data structure when a new datagram is received and it will also check every second if any musician in the array is no longer active and will remove it if so.

Task 2: implement a "musician" Node.js application

# Topic
Question In a JavaScript program, if we have an object, how can we serialize it in JSON?
With JSON.stringify(myObject)
Question What is npm?
Node Package Manager, this is used to managed project dependencies when we need to work with other Node modules
Question What is the npm install command and what is the purpose of the --save flag?
It is used to install a new dependency to the project and add it to the package.json file. The flag --save indicates that the dependency is needed for production environement. We can use --save-dev or -D to tell npm the dependency is for development only.
Question How can we use the https://www.npmjs.com/ web site?
We can search for a Node module we need like for generating a unique ID.
Question In JavaScript, how can we generate a UUID compliant with RFC4122?
We can use the uuid package. It provides a v4 function we can call to generate a new unique ID.
Question In Node.js, how can we execute a function on a periodic basis?
We use the function setInterval(callback, delay_in_ms[, ...args]). This global function will call the specified callback with given args every x millisecond(s).
Question In Node.js, how can we emit UDP datagrams?
We first need to create a datagram socket. After that we can use the send method on the socket to send a buffer to specific address with port number.
Question In Node.js, how can we access the command line arguments?
We use the process.argv array. In our case. the first one (process.argv[0]) is node, the second one (process.argv[1]) is the script file and the third (process.argv[2]) will be the instrument.

Task 3: package the "musician" app in a Docker image

# Topic
Question How do we define and build our own Docker image?
With a Dockerfile extending the node image. First, we copy the content of the current directory then we install dependencies. And finally, we start the node app.
The image can be built with : docker build -t res/musician .
Question How can we use the ENTRYPOINT statement in our Dockerfile?
We use ENTRYPOINT to specify the command to execute at the start of the container. In our case, start our node application app.js.
Question After building our Docker image, how do we use it to run containers?
We can start a musician with docker run res/musician <instrument>
Instrument can be piano, trumpet, flute, violin or drum.
Question How do we get the list of all running containers?
We can list the running containers with : docker ps
Question How do we stop/kill one running container?
To gently stop a container, use : docker stop <container id or name>. This will send a SIGTERM then a SIGKILL after a grace period (generally 10 seconds)
To brutally stop a container, use : docker kill <container id or name>. This will immediately send a SIGKILL.
Question How can we check that our running containers are effectively sending UDP datagrams?
We can use wireshark to monitor the traffic of our containers or we can use our monitor image which is a simple web app that allow us to visualize active musician (see Task 5).

Task 4: implement an "auditor" Node.js application

# Topic
Question With Node.js, how can we listen for UDP datagrams in a multicast group?
After we bound the datagram socket to the chosen port, we need to subscribe to the multicast group. We use the addMembership function with the multicast group address as parameter.
Question How can we use the Map built-in object introduced in ECMAScript 6 to implement a dictionary?
We used a simple array instead of a Map. We used indexOf to find an existing musician.
Question How can we use the Moment.js npm module to help us with date manipulations and formatting?
We used vanilla JavaScript dates :) We can use toLocaleString to format dates.
Question When and how do we get rid of inactive players?
We check every second in the auditor for inactive musicians. We used the filter function on the array to get back only active musicians.
Question How do I implement a simple TCP server in Node.js?
Just call the createServer function from the net module. After that we can call listen on the server instance with a given port to bind it.

Task 5: package the "auditor" app in a Docker image

# Topic
Question How do we validate that the whole system works, once we have built our Docker image?
We made another image named "monitor" that allow us to monitor all active musicians in a simple React JS web application. The script deploy.sh start the auditor, the monitor and 10 musicians so we can validate that everything is working as intended at localhost:5000. The auditor expose the musicians array through an API (localhost:3030). The monitor just request the API each second to refresh its UI.

Constraints

Please be careful to adhere to the specifications in this document, and in particular

  • the Docker image names
  • the names of instruments and their sounds
  • the TCP PORT number

Also, we have prepared two directories, where you should place your two Dockerfile with their dependent files.

Have a look at the validate.sh script located in the top-level directory. This script automates part of the validation process for your implementation (it will gradually be expanded with additional operations and assertions). As soon as you start creating your Docker images (i.e. creating your Dockerfiles), you should try to run it.

teaching-heigvd-res-2020-labo-orchestra's People

Contributors

balsigergil avatar jul0105 avatar wasadigi avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.