5 releases (3 breaking)

0.3.1 May 27, 2024
0.3.0 Apr 22, 2024
0.2.0 Mar 25, 2024
0.1.0 Mar 19, 2024
0.0.0 Feb 8, 2023

#56 in WebSocket

Download history 710/week @ 2024-07-24 456/week @ 2024-07-31 587/week @ 2024-08-07 225/week @ 2024-08-14 657/week @ 2024-08-21 1363/week @ 2024-08-28 1363/week @ 2024-09-04 1189/week @ 2024-09-11 926/week @ 2024-09-18 693/week @ 2024-09-25 874/week @ 2024-10-02 543/week @ 2024-10-09 794/week @ 2024-10-16 1137/week @ 2024-10-23 702/week @ 2024-10-30 366/week @ 2024-11-06

3,115 downloads per month

EUPL-1.2

160KB
4K SLoC

This crate wraps the Janus WebSocket asynchronous API to provide a more or less idiomatic Rust API.

For this the client internally resolves futures based on the incoming responses and their respective transaction identifier. This is hidden to provide an API where you can simply call a function and .await the response. Thus this creates needs to be run in a async/.await runtime. Currently we only support the tokio runtime.

Examples

 # use opentalk_janus_client::types::outgoing;
 # use opentalk_janus_client::{JanusPlugin, Client, RabbitMqConfig, ClientId};
 # use tokio::sync::{broadcast,mpsc};
 # use std::sync::Arc;
 # tokio_test::block_on(async {
 let (sink, _) = mpsc::channel(1);
 let connection = lapin::Connection::connect("amqp://janus-backend:5672", lapin::ConnectionProperties::default()).await.unwrap();
 let channel = connection.create_channel().await.unwrap();
 let config = RabbitMqConfig::new_from_channel(channel, "janus-gateway".into(), "to-janus".into(), "from-janus".into(), "opentalk-signaling".into());
 let client = Client::new(config, ClientId("".into()), sink).await.unwrap();
 let session = client.create_session().await.unwrap();
 let echo_handle = session
     .attach_to_plugin(JanusPlugin::Echotest, None)
     .await
     .unwrap();

 let echo = echo_handle
     .send(outgoing::EchoPluginUnnamed {
             audio: Some(true),
             ..Default::default()
     })
     .await.unwrap();
 println!("Echo {:?}, JSEP: {:?}", &echo.0, &echo.1);
 # });

Furtermore you can wrap the API and build upon that similar to spreed

pub struct SubscriberClient(Handle);
impl SubscriberClient {
    /// Joins a Room
    pub async fn join_room(&self, candidate: String ) {
        let room_id: RoomId = 2.into();
        let feed_id: FeedId = 1.into();
        let request = VideoRoomPluginJoinSubscriber::new(room_id, feed_id);
        self.0.send(request).await;
    }
}

pub struct PublisherClient(Handle);
impl PublisherClient {
    /// Sends the candidate SDP string to Janus
    pub async fn send_candidates(&self, candidate: String ) {
        self.0.trickle(TrickleMessage::Candidate(TrickleCandidate{
            candidate: "candidate:..".to_owned(),
            sdp_m_line_index: 1
        })).await;
    }
}
tokio_test::block_on(async {
let (sink, _) = mpsc::channel(1);
let connection = lapin::Connection::connect("amqp://janus-backend:5672", lapin::ConnectionProperties::default()).await.unwrap();
let channel = connection.create_channel().await.unwrap();
let config = RabbitMqConfig::new_from_channel(channel, "janus-gateway".into(), "to-janus".into(), "from-janus".into(), "opentalk-signaling".into());
let client = opentalk_janus_client::Client::new(config, ClientId("".into()), sink).await.unwrap();
let session = client.create_session().await.unwrap();

let echo_handle = session
    .attach_to_plugin(JanusPlugin::VideoRoom, None)
    .await
    .unwrap();
let publisher = PublisherClient(echo_handle);

let echo_handle = session
    .attach_to_plugin(JanusPlugin::VideoRoom, None)
    .await
    .unwrap();
let subscriber = SubscriberClient(echo_handle);
});
}

Features

Specific plugins are hidden behind feature flags. Supported Janus plugins can be enabled with the following cargo features

  • echotest for the EchoTest Janus plugin
  • videoroom for the VideoRoom Janus plugin

By default echotest and videoroom are enabled.

Dependencies

~12–23MB
~345K SLoC