WebRTC API Design Proposal - mozilla-services/remote-worker-server GitHub Wiki

Remote worker server is a service that enable you to run Gecko worker remotely on a Gecko headless sandbox in the cloud and communicate with it through a WebRTC data channel.

Contents

Use the OAuth token with this header:

Authorization: Bearer <oauth_token>
note: This approach is straightforward, but implies the remote worker server API to check the token on the FxA server at each request. However the FxA team told us it is the way to go as they handle caching on their side.

The GET /v1/fxa-oauth/params endpoint can be use to get the configuration in order to trade the Firefox Account BrowserID with a Bearer Token. See Firefox Account documentation about this behavior

$ http GET http://localhost:8000/v0/fxa-oauth/params -v

GET /v0/fxa-oauth/params HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Host: localhost:8000
User-Agent: HTTPie/0.8.0


HTTP/1.1 200 OK
Content-Length: 103
Content-Type: application/json; charset=UTF-8
Date: Thu, 19 Feb 2015 09:28:37 GMT
Server: waitress

{
    "client_id": "89513028159972bc",
    "oauth_uri": "https://oauth-stable.dev.lcip.org",
    "scope": "profile"
}

Remote Worker server scope

The remote worker server API will eventually have to handle a dedicated OAuth scope (e.g. remote-worker-server).

So far the FxA server only handles the profile scope.

The returned value is a JSON mapping containing:

  • hello: the name of the service ("remote-worker-server")
  • version: complete version ("X.Y.Z")
  • url: absolute URI (without a trailing slash) of the API (can be used by client to build URIs)
  • eos: date of end of support in ISO 8601 format ("yyyy-mm-dd", undefined if unknown)
  • documentation: Service Documentation URL.

Return the status of each service the remote-worker-server depends on. The returned value is a JSON mapping containing:

  • pubsub true if operational
  • gecko-cluster true if operational

Return 200 if the connection with each service is working properly and 503 if something doesn't work.

When a client wants to create a remote worker she connects to the websocket endpoint and send the Worker source URL as well as her WebRTC SDP offer.

Starting a worker

When the client connects the websocket it sends the:

{
    "messageType": "hello",
    "action": "client-hello",
    "authorization": "Bearer <oauth-token>",
    "source": "https://worker.uri/source.js",
    "webrtcOffer": "<sdp-offer>"
}

When the gecko worker connects the worker channel, it sends the:

{
    "messageType": "hello",
    "action": "worker-hello",
    "workerId": "''<worker_id>''"
    "webrtcAnswer": "<sdp-answer>"
}

Connected standza

As soon as the party is connected to the WebRTC data channel, they send:

{
    "messageType": "progress",
    "workerId": "''<worker_id>''",
    "status": "connected"
}

When the client sent and has got the connected status it closes the websocket.

WebRTC Data channel

As soon as both the client and the server are connected together on the websocket, the WebRTC data channel is setup between the two pairs and then can start to talk as in a normal worker channel.

As soon as the data channel is setup, the websocket is closed.

Any messages from the client is send to the worker and any messages from the worker is send to the client.

Termination and errors

I case an error occured, the following stanza is sent on the websocket:

{
    "messageType": "progress",
    "workerId": "''<worker_id>''",
    "status": "terminated",
    "reason": "closed"
}

Termination reasons

Reason Client Worker Note
client-closed   The client WSS connection closed unexpectedly.
worker-closed   The worker connection closed unexpectedly.
client-webrtc-failed   The client WebRTC channel setup failed.
worker-webrtc-failed   The worker WebRTC channel setup failed.

After a termination standza the worker is killed and both the websocket and the data channel are closed. In case the worker doesn't have a data channel anymore, it dies.

When the gecko starts, it connects to the server with the websocket protocol.

On wss://server_host/worker

When the gecko connects the websocket, it sends:

{
    "messageType": "hello",
    "action": "worker-hello",
    "geckoID": "''<gecko_profile_id>''"
}

The geckoID is the unique id that we will route the same user to. It should stay the same for the same gecko profile.

When the server receive a SDP offer, it will generate a worker id and send on the Gecko headless websocket:

{
    "messageType": "new-worker",
    "userId": "''<user_id>''",
    "workerId": "''<worker_id>''",
    "source": "https://worker.uri/source.js",
    "webrtcOffer": "<sdp-offer>"
}

Then the gecko server should create the worker and return:

{
    "messageType": "worker-created",
    "workerId": "''<worker_id>''",
    "webrtcAnswer": "<sdp-answer>"
}

When the gecko stops it just close the connection.

⚠️ **GitHub.com Fallback** ⚠️