CSC/ECE 517 Spring 2015 M1502 WSRA

From Expertiza_Wiki
Jump to navigation Jump to search

Implement Rust Websocket

This project concentrates on implementing Rust WebSocket API for Mozilla's web browser engine, Servo

Introduction

Servo<ref> https://github.com/servo/servo </ref> is a Web Browser engine written in Rust. It is an experimental project build that targets new generation of hardware: mobile devices, multi-core processors and high-performance GPUs to obtain power efficiency and maximum parallelism. Implementing WebSocket API for the Servo engine would allow a persistent single TCP socket connection to be established between the client and server that will provide bi-directional, full duplex, messages to be instantly exchanged with little overhead resulting in a very low latency connection and supporting interactive, dynamic applications.

Rust

Rust <ref> https://github.com/rust-lang/rust </ref> is a Systems programming language built in Rust itself that is fast, memory safe and multithreaded, but does not employ a garbage collector or otherwise impose significant runtime overhead. Rust is able to provide both control over hardware and safety which is not the case with other programming languages like C, C++, Python that provide only either control or safety but not both.

WebSocket

WebSockets is a protocol that provides full-duplex channel for a TCP connection and makes it possible to open an interactive communication session between the user's browser and a server. With WebSockets, you can send messages to a server and receive event-driven responses without having to request the server for a reply. The WebSocket specification defines an API to establish a "socket" connection between a web browser and a server. This establishment involves a handshake following which there is a persistent connection between the client and the server and both parties can start sending data asynchronously.

Cargo and Crate

Cargo <ref>http://doc.crates.io/guide.html</ref> is a application level package manager that allows Rust projects to declare their various dependencies. Cargo resembles the Bundler in Rails that is used to run Rails app, install required Gems mentioned in the Gemfile. Gemfile correspond to Cargo.toml file and Gem correspond to Crates

Cargo introduces two metadata files with various bits of project information, fetches and builds project's dependencies, invokes rustc or another build tool with the correct parameters to build the project.

Project Description

The goal of this project is to implement WebSocket functionality in to Servo using the Rust WebSocket project. Once this is completed, tests following the HTML spec [1] for websockets should pass, as the same spec will be driving development. The project will be completed when the following conditions are true, and all tests have passed.

  • The client can establish a websocket connection
  • The client can send objects to the server through the websocket
  • The client can receive objects from the server through the websocket
  • The client can successfully close the Websocket

If Servo, as the client, is able to successfully perform all of these tasks, then our project will be completed.

Requirement Analysis

The requirements for the implementation is well detailed in the HTML spec shown here [2]. The majority of the requirements have to do with the feedback for the protocol. The entire reading can be seen there.

Outside of the HTML spec, a couple other requirements are necessary. First, Servo must successfully compile with the websocket components included. There are a number of warnings currently with compiling Servo not related to Websocket, but no new ones should be introduced.

Second, we should pass a set of tests already included in Servo's tests/wpt/web-platform-tests/websockets directory. These tests determine if the current websocket implementation fulfills all the requirements for Servo's use.

Finally, we should successfully issue pull requests for each feature as it is completed.

Implementation

The full implementation specs are outlined here: https://github.com/servo/servo/wiki/WebSocket-student-project

In general the websocket has 3 functions:

  • Open() - Initiates and connects the websocket to the server. Once the connection is open, hands receives.
  • Send() - Sends application data to the server
  • Close() - Closes the websocket connection

In addition the websocket has the following attributes:

  • readyState - indicates the current state of the websocket. The websocket can be in one of the five states below:
    • Connecting - an initial connection handshake has been started but the server has not responded to the handshake yet
    • Open - the connection has been established (server has responded to the initial connection handshake)
    • Closing - an initial close connection handshake has been started but the server has not responded to the handshake yet
    • Closed - the connection has been closed (server has acknowledged the closing handshake and responded)
  • Extensions - Extensions are being used by the websocket (see full specs link above)
  • Protocol - Protocols being used by the websocket (see full specs link above)
  • bufferedAmount - returns how many bytes of application data has been buffered in the websocket thus far (unsent data)

Design Patterns

Factory Pattern
For every web application application running on the web browser that requires a websocket for communicating with the server, a new thread needs to be spawned that creates a client end of the socket associated with the web app. Spawning this thread can be considered to be similar to instantiating an object for which Factory Pattern can be employed.
Thread Pool Pattern
Servo's primary objective was to provide concurrency. This concurrency can be attained by scheduling tasks which can be run in parallel. Threads help execute these tasks in parallel. Thread Pool Pattern helps manage these thread. For example, one thread could be to accept new requests for websockets, as a result of which new thread would be spawned (client side of websocket) for that application.

Test Cases

The test cases for WebSocket are already implemented and included in Servo. Servo uses a testing system which allows skipping of features not included, or passed. Therefore, when the WebSocket tests are included, it is not only necessary to know how to run them, it is important to be able to use the tools that automatically update the tests passed as well.

First, to include the websocket tests, add the following lines in the tests/wpt/include.ini file:
[websockets]
skip: false

Then, you will need to run the tests, and update the test expectations from the results. To run the tests, do the following command:
./mach test-wpt --log-raw /tmp/servo.log

The servo.log will be used to update the test expectations. Once the tests have finished, update the test expectations using the following command:
./mach update-wpt /tmp/servo.log

Further reading on updating the test harness for Servo can be found here [3]

In addition to the test cases provided by Servo, we included a test websocket page which used all of the expected interface for a websocket. This was more a design to interface, where each stage of including a function could be seen on progress on our test page. This test page came from her: [4] and is stored in tests/html/test-websocket.html. To run this test, use the following command:
./mach run tests/html/test-websocket.html

This code will open a websocket, print connected, send a message, then print a received message before closing. As stated before, this is more a test to interface tool, instead of testing the conformance to spec and robustness of the code created.

Further Readings

HTML Spec for WebSockets
Mozilla Websocket Project Page
Servo github
Rust Websocket

References

<references/>