CSC/ECE 517 Spring 2015/oss M1502 GVJ

From Expertiza_Wiki
Jump to navigation Jump to search


Implementing the WebSocket API
This project concentrates on implementing Rust WebSocket API for Mozilla's web browser engine, Servo. The project work involved making the Servo's script depend on WebSocket crate.

Introduction to Mozilla Servo

Servo<ref> https://github.com/servo/servo </ref> is a Web Browser engine written in Rust. Servo 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.

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 was to incorporate the websocket crate in to servo, using the up to date rust websocket crate instructions. To do that, Rust's crate manager and how it interacted with servo's Mach tool was explored.

The Crate Manager

To incorporate new crates in to a project in rust, two main tasks are needed. First, depending on the crate that is used, a dependency needs to be added to the relevant Cargo.toml. For servo and websocket, that Cargo.toml is related to the script component, found in servo's components/script folder. To add a dependency to the Cargo.toml file, a couple different methods are available, both with separate advantages.

The first method is the simplest, and allows specification of crate versions through a method similar to Ruby gemfiles. Simply navigate to the [dependencies] section of the Cargo.toml, and add the crate and the version, like this example with websocket:

[dependencies]
...
websocket = "0.11.0"

You can vary this with other options, like ~, as in Ruby, to specify that the latest crate should be loaded or an exact version.

The second method of adding a dependency allows for far more flexibility. A crate's git repository can be added directly to the Cargo.toml, as well as many options to use particular branches, versions, and revisions. The syntax for these dependencies is shown below.

[dependency.crate_name]
git = "path_to_crate_git"
//other options

Other options that are particularly useful include the ability to choose branches and revisions. Each of these options are shown below.

branch = "name_of_branch"
rev = "hash_of_commit"


The next step for adding a crate to a servo project requires modifying the main.rs or lib.rs, depending on which is being used for the project. Normally, the main.rs is used for the primary package, where other parts of a project may only use a lib.rs. To add a crate in either of these files, use the code shown below.

extern crate crate_name

Further uses of Cargo and other syntax beyond what is discussed in this article can be found here.

Including Rust Websocket in Servo

To include the Rust Websocket<ref>https://github.com/cyderize/rust-websocket</ref> crate in to Servo, an earlier version of the crate needs to be used. This is because of hyper crate dependencies. In hyper 0.3.2, method accesses were modified. Servo runs on a precompiled version of rust, one that supports hyper 0.3.0. Because of the changes in hyper 0.3.2, an earlier version of Rust Websocket that relies on hyper 0.3.0 needed to be used.

The files for implementing the websocket functions can be found in the webidl folder inside of components/script directory. To allow these files to be used, our project needed to make changes to servo to allow the websocket crate to be compiled. The first file change that is necessary lies in components/script/Cargo.toml. The websocket dependency of the correct version needs to be added here.

[dependencies]
websocket = "0.11.0"

The second file, as described above for adding the websocket crate, is also in components/script. For this section, since the servo component is the main component, the file that needs editing is lib.rs instead of main.rs. The file is modified by adding this line with the other extern lines.

extern ...
extern crate websocket;
...

Once these files have been modified, return to the base servo directory, and run ./mach build to compile the websocket library in to Servo.

References

<references/>