Janus Code analysis 1

Abstract

Janus gateway code analysis 1

Authors

Walter Fan

Status

v1.0

Updated

2026-08-17

Overview

Janus 是由 Meetecho 开发的开源 WebRTC 服务器网关,采用 C 语言编写,以高性能和灵活的插件架构著称。 它本身不提供具体的通信功能,而是通过插件系统支持各种应用场景,如视频会议、直播、SIP 网关等。

项目地址: https://github.com/meetecho/janus-gateway

架构概述

Janus 的整体架构分为三层:

        flowchart TB
  T["Transport Layer<br/>HTTP/HTTPS, WebSocket, RabbitMQ"]
  subgraph Core["Janus Core janus.c"]
    S[Session 管理]
    H[Handle 管理]
    ICE[ICE/DTLS/SRTP 处理]
    P[Plugin 调度]
  end
  PL["Plugin Layer<br/>VideoRoom, AudioBridge, Streaming"]
  T --> Core --> PL
    
  • Transport Layer: 负责与客户端的信令通信,支持多种传输协议

  • Janus Core: 核心引擎,管理 WebRTC 连接的建立和媒体转发

  • Plugin Layer: 业务逻辑层,每个插件实现特定的应用场景

核心模块 (janus.c)

janus.c 是 Janus 的主入口和核心调度模块,主要包含以下功能:

Session 与 Handle

  • Session (janus_session): 代表一个客户端连接,包含一个或多个 Handle

  • Handle (janus_ice_handle): 代表一个 WebRTC PeerConnection,关联到一个 Plugin

// 核心数据结构
struct janus_session {
  guint64 session_id;
  GHashTable *ice_handles;   // handle_id → janus_ice_handle
  janus_transport *source;   // 关联的 Transport
  volatile gint timeout;
  volatile gint destroyed;
};

struct janus_ice_handle {
  guint64 handle_id;
  janus_session *session;
  janus_plugin *app;         // 关联的 Plugin
  void *app_handle;          // Plugin 侧的 handle
  janus_ice_stream *stream;  // ICE stream
  // ...
};

消息处理流程

客户端发送的 JSON 消息经过以下流程处理:

  1. Transport 层接收消息,调用 janus_process_incoming_request()

  2. 根据消息类型分发:create (创建 Session)、attach (关联 Plugin)、message (转发给 Plugin)

  3. Plugin 处理完成后,通过回调将结果返回给客户端

插件系统

Janus 的插件系统是其最大的设计亮点。每个插件实现 janus_plugin 接口:

struct janus_plugin {
  // 插件元信息
  const char *(*get_name)(void);
  const char *(*get_description)(void);

  // 生命周期
  int (*init)(janus_callbacks *callback, const char *config_path);
  void (*destroy)(void);

  // 会话管理
  void (*create_session)(janus_plugin_session *handle, int *error);
  void (*destroy_session)(janus_plugin_session *handle, int *error);

  // 消息处理
  struct janus_plugin_result *(*handle_message)(
      janus_plugin_session *handle, char *transaction,
      json_t *message, json_t *jsep);

  // 媒体回调
  void (*incoming_rtp)(janus_plugin_session *handle,
                       janus_plugin_rtp *packet);
  void (*incoming_rtcp)(janus_plugin_session *handle,
                        janus_plugin_rtcp *packet);
};

常用的官方插件:

  • janus_videoroom: SFU 模式的视频会议室,支持 Simulcast 和 SVC

  • janus_audiobridge: MCU 模式的音频混音桥

  • janus_streaming: 媒体流分发 (RTP 转 WebRTC)

  • janus_sip: SIP 网关,连接 WebRTC 和传统电话网络

  • janus_recordplay: 媒体录制和回放

ICE 处理

Janus 的 ICE 处理由 ice.cice.h 实现,基于 libnice 库:

  1. Candidate 收集: 收集 host、srflx、relay 候选地址

  2. 连通性检查: 通过 STUN Binding Request 进行 ICE 连通性检查

  3. DTLS 握手: ICE 连接建立后进行 DTLS-SRTP 密钥协商

  4. SRTP 加密: 使用协商的密钥对 RTP/RTCP 进行加解密

// ICE 连接建立的关键回调
static void janus_ice_cb_nice_recv(NiceAgent *agent,
    guint stream_id, guint component_id,
    guint len, gchar *buf, gpointer data) {
  // 判断是 DTLS 还是 SRTP 数据
  // DTLS: 交给 OpenSSL 处理握手
  // SRTP: 解密后转发给 Plugin
}

媒体数据在 Janus 内部的转发路径:

        flowchart LR
  A[Client A] --> ICE1[ICE]
  ICE1 --> Dec[SRTP 解密]
  Dec --> Plugin["Plugin 如 VideoRoom"]
  Plugin --> Fwd[转发给其他参与者]
  Plugin --> Enc[SRTP 加密]
  Enc --> ICE2[ICE]
  ICE2 --> B[Client B]
    

参考资料