Mobile Development 14 min read

Optimizing Cross‑Platform WebSocket Connections with Cronet for Mobile Live Streaming

By migrating the CatEar FM live‑streaming app’s WebSocket layer to Chromium’s Cronet network stack, the team unified cross‑platform code, added customizable DNS and proxy support, and cut handshake latency by roughly 150 ms on Android and 250 ms on iOS, paving the way for future HTTP/2 and HTTP/3‑based WebSocket transports.

Bilibili Tech
Bilibili Tech
Bilibili Tech
Optimizing Cross‑Platform WebSocket Connections with Cronet for Mobile Live Streaming

Long‑living connections such as push, real‑time communication, and signaling are essential for modern mobile applications. In the live‑streaming service of the CatEar FM platform, WebSocket is used as the foundation for real‑time communication.

The main optimization target is the time a user spends to successfully enter a live room, which includes the room‑info API call, WebSocket handshake, and the first video frame. The article first explains why WebSocket was chosen over other protocols and outlines the challenges of the current implementation, such as a 500‑600 ms handshake latency (DNS + TCP + TLS + HTTP Upgrade) compared with a normal HTTPS request.

Four key requirements for the next iteration are:

Unified multi‑platform code with clear error logging.

Customizable DNS (httpdns, DNS cache, IPv6 strategies).

Support for HTTP proxy to aid testing.

Future‑proofing for continued WebSocket standard evolution.

Several cross‑platform libraries were evaluated:

websocketpp – client/server library, no longer actively maintained.

libwebsockets – used for signaling in user‑mic scenarios.

cronet – Chromium’s network stack, already the underlying library for the current HTTP transport.

Because cronet already contains a complete WebSocket implementation and fits the mobile integration model, the team decided to adopt cronet for the next‑generation solution. The migration involved adapting the net/websockets module, adding active ping support, and removing the Origin header check.

The following native interface IDL (wrapped in code tags) shows the key WebSocket callback and request definitions used in the implementation:

// Counterpart of UrlRequestCallback for websocket.
[Abstract]
interface WebSocketCallback {
  /**
   * The message type invoked by {@code OnMessage()}.
   * 目前只能收到 text 或者 binary 两种. continuation 已被合并处理.
   */
  enum MESSAGE_TYPE {
    CONTINUATION = 0,
    TEXT = 1,
    BINARY = 2,
  };

  OnAddChannelResponse(WebSocket request, UrlResponseInfo info, string extensions);
  OnMessage(WebSocket request, MESSAGE_TYPE type, Buffer buffer);
  OnDropChannel(WebSocket request, bool was_clean, uint16 code, string reason);
  OnFailed(WebSocket request, Error error);
  OnCanceled(WebSocket request);
};

/**
 * Controls an Websocket request.
 * Initialized by InitWithParams().
 * Note: All methods must be called on the Executor passed to InitWithParams().
 */
interface WebSocket {
  // see https://www.iana.org/assignments/websocket/websocket.xhtml#opcode.
  enum OPCODE {
    CONTINUATION_FRAME = 0,
    TEXT_FRAME = 1,
    BINARY_FRAME = 2,
    CONNECTION_CLOSE_FRAME = 8,
    PING_FRAME = 9,
    PONG_FRAME = 10,
  };

  [Sync]
  InitWithParams(Engine engine,
                string url,
                WebSocketParams params,
                WebSocketCallback callback,
                Executor executor) => (RESULT result);

  [Sync]
  Start() => (RESULT result);

  [Sync]
  ReadFrames() => (RESULT result);

  [Sync]
  SendFrame(bool fin, OPCODE op_code, Buffer buffer) => (RESULT result);

  [Sync]
  Send(OPCODE op_code, Buffer buffer) => (RESULT result);

  [Sync]
  Close(uint16 code, string reason) => (RESULT result);

  Cancel();

  [Sync]
  IsDone() => (bool done);
};

// 请求参数.
struct WebSocketParams {
  /**
   * Array of HTTP headers for this request.
   */
  array
request_headers;
};

The migration yielded measurable performance gains: Android connection latency improved by ~150 ms and iOS by ~250 ms, mainly due to unified DNS handling and native I/O optimizations. Error reporting also became clearer, facilitating faster debugging.

Future directions include adopting WebSocket over HTTP/2 (RFC 8441) and HTTP/3 (RFC 9220), which simplify the handshake and can further reduce latency when supported by the server. Cronet already supports these protocols, so the team plans to experiment with QUIC‑based transport for WebSocket in upcoming releases.

mobile developmentcross‑platformperformance optimizationWebSocketCronetnetwork protocol
Bilibili Tech
Written by

Bilibili Tech

Provides introductions and tutorials on Bilibili-related technologies.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.