Skip to content

Application Protocol

Harry Zhang edited this page Jun 18, 2018 · 4 revisions

Overview

The Application Protocol describes how the Client and the Server transfer Application Events.

Application Event, or Event, is the way of notifying the connection counterpart the happening of something.

The stateless Application Procotol build on a connection established with the Transport Protocol. It hides this connection from applications completely and only exposes an interface as follows:

Interface

The interface of the Client-side Connection.

Note that this is not the documentation of the actual implementation in bilibili-danmaku-client. This section only describes the exposed interface of the Application Protocol to Clients and Servers in pseudocode. Also, the implementation might not 100% conform to this interface. For the implementation documentation, see the code.

open()

    function open(room: int): Connection

Opens the conection.

  • param room: The ID of the Live Room to connect to.
  • return: The Connection. Non-null. Should be in opening state.

Connection

    class Connection {
        room: int,
        state: String,
    }
  • property room: The ID of the Live Room that this Connection connects to. Read-only.
  • property state: The current state of this Connection. See lifecycle.

Connection.close()

    function Connection.close(): void

Same as Connection.close() of the Transport Procotol.

Connection.send()

    function Connection.send(event: Event): void

Call Connection.send() of the Transport Procotol, with event.toJson().

  • param event: The Event to send. Required.

Connection.on()

    function Connection.on(event: String, callback: Function): void

Add callback as listener to event. Recommended to call this right after open(). Listeners will be called on order of on(), if the former listener throws an error, behavior is undefined. For event definitions see events.

Event

    class Event {
        name: String,
        abstract toJson(): Object,
    }
  • property name: The name of this Event. Read-only.
  • method toJson(): Get the JSON representation of the data of this Event, send through the Transport Protocol.

Event is an abstract class and is often subclassed according to the actual event type. However, due to reason described here, Event subclasses are defined in another Wiki page, with where the definitions are paired with their API documentation, so browsing will a lot easier there.

Lifecycle

Since the Application Protocol is statless, it uses the Connection.state property only to hide details of the Transport Protocol from Clients and Servers.

Therefore, the lifecycle of the Application Protocol simply inherits that of the Transport Protocol.

Events

The Application Protocol inherits all the lifecycle events of the Transport Protocol. (open, close, and error)

Moreover, the Application Protocol defines a event event, emitted when an Event is received from the connection counterpart. Applications can use Event.name to distinguish different types of events.

The protocol

This section only describes the Application Protocol on the Client side.

Since the Transport Protocol requires a Handshake JSON to be specified upon opening the connection, the Application Protocol specifies the Handshake JSON as follows:

    {
        protover: int,
        platform: string,
        clientver: string,
        uid: int,
        roomid: int,
    }
  • property protover: The version of the Application Protocol, currently 1.
  • property platform: The string representing the running platform of the Client, probable value is currently only web.
  • property clientver: The version of the implementation of the Client, currently '1.4.3'. Note that this is not necessarily equal to the version of the bilibili-danmaku-client package.
  • property uid: The ID of the user that is using the Client. Currently 0.
  • property roomid: The ID of the Live Room that this Connection is connecting to. Value is Connection.room.

On sending an Event, Event.toJson() is used to convert it into JSON and sent through the Transport Protocol.

On receiving an JSON, the Application Protocol runs the following steps to try to convert it into an Event:

  1. Verify that the JSON received is a JSON Object. Otherwise, throw an error.
  2. Read the cmd attribute of the received JSON. On error, throw it.
  3. Compare the cmd with the entries in the Events Registry.
    1. On match, run the constructor of the matched subclass of Event to construct an Event.
    2. On no match, throw an error.
    3. On error running the constructor, throw it.
  4. Return the Event.

If this process returned an Event, feed it to the application by emitting the event event. If this process thrown an error, log the error and ignore the JSON. The connection SHOULD not close on such an error.

The Events Registry is a map from event cmd values to subclasses of Event. Due to the reason described here, they are defined in another Wiki page.

Why another page

The key point is that events types are invented and deprecated frequently and their definitions are due to change at any time. On the contrary, the Application Protocol does not, is not designed to be, and should not change very often.

Actually, in the protocol details we can see that a protover is sent, which remains 1 however the event types evolves. This also shows that the Application Protocol is more consistant and general.

And therefore, this Wiki page, named Application Protocol, should not contain those inconsistant information about the event types.

And therefore they should be placed in another Wiki page.