Skip to content
This repository has been archived by the owner on Aug 25, 2021. It is now read-only.

Configure Member's RPC connection settings via Control API (#27) #95

Merged
merged 22 commits into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ All user visible changes to this project will be documented in this file. This p
### BC Breaks

- Configuration:
- Rename `[server]` section of Client API HTTP server as `[server.client.http]` ([#33]).
- Rename `[server]` section of Client API HTTP server as `[server.client.http]` ([#33]);
- RPC messaging:
- Reverse `Ping`/`Pong` naming: server sends `Ping` and expects `Pongs` from client now. ([#75]).

Expand All @@ -29,6 +29,7 @@ All user visible changes to this project will be documented in this file. This p
- gRPC Control API callbacks ([#63]):
- `on_join`;
- `on_leave`.
- Configuration of the `Member`'s RPC connection settings by Control API ([#95]).
- Signalling:
- Dynamic `Peer`s creation when client connects ([#28]);
- Auto-removing `Peer`s when `Member` disconnects ([#28]);
Expand Down Expand Up @@ -64,6 +65,7 @@ All user visible changes to this project will be documented in this file. This p
[#84]: /../../pull/84
[#86]: /../../pull/86
[#94]: /../../pull/94
[#95]: /../../pull/95



Expand Down
26 changes: 14 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions _dev/specs/pub-pub-video-call.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ spec:
credentials: test
on_join: "grpc://127.0.0.1:9099"
on_leave: "grpc://127.0.0.1:9099"
idle_timeout: 1m
reconnect_timeout: 1m
ping_interval: 10s
spec:
pipeline:
# Media element which is able to receive media data from client
Expand All @@ -28,6 +31,9 @@ spec:
credentials: test
on_join: "grpc://127.0.0.1:9099"
on_leave: "grpc://127.0.0.1:9099"
idle_timeout: 1m
reconnect_timeout: 1m
ping_interval: 10s
spec:
pipeline:
publish:
Expand Down
11 changes: 9 additions & 2 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,26 @@
# Duration, after which remote RPC client will be considered idle if no
# heartbeat messages received.
#
# This duration can be overridden for some 'Member' by Control API spec.
#
# Env var: MEDEA_RPC__IDLE_TIMEOUT
# Default:
# idle_timeout = "10s"

# Duration, after which the server deletes client session if remote RPC client
# does not reconnect after it is idle.

# Duration, after which the server deletes the client session if
# the remote RPC client does not reconnect after it is idle.
#
# This duration can be overridden for some 'Member' by Control API spec.
#
# Env var: MEDEA_RPC__RECONNECT_TIMEOUT
# Default:
# reconnect_timeout = "10s"

# Interval between pings that server sends to clients.
#
# This duration can be overridden for some 'Member' by Control API spec.
#
# Env var: MEDEA_RPC__PING_INTERVAL
# Default:
# ping_interval = "3s"
Expand Down
12 changes: 12 additions & 0 deletions docs/rfc/0001-control-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ spec:
on_join: "grpc://127.0.0.1:9091"
# Fires when "caller" client disconnects from media server via WebSocket.
on_leave: "grpc://127.0.0.1:9091"
# Duration, after which remote RPC client will be considered idle if no
# heartbeat messages received.
idle_timeout: 1m
# Duration, after which the server deletes the client session if the remote
# RPC client does not reconnect after it is idle.
reconnect_timeout: 3m
# Interval of sending pings from the server to the client.
ping_interval: 10s
pipeline:
# Media element which is able to receive media data from client via WebRTC.
publish:
Expand Down Expand Up @@ -781,6 +789,10 @@ message Member {
optional string on_join = 1;
optional string on_leave = 2;
map<string, Member.Element> pipeline = 3;
optional string credentials = 4;
optional uint64 idle_timeout = 5;
optional uint64 reconnect_timeout = 7;
optional uint64 ping_interval = 8;

message Element {
oneof el {
Expand Down
31 changes: 24 additions & 7 deletions jason/e2e-demo/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,25 @@ const controlDebugWindows = {
let memberId = container.getElementsByClassName('control-debug__id_member')[0].value;
let credentials = container.getElementsByClassName('member-spec__credentials')[0].value;

await controlApi.createMember(roomId, memberId, credentials);
let idleTimeout = container.getElementsByClassName('member-spec__idle-timeout')[0].value;
let reconnectTimeout = container.getElementsByClassName('member-spec__reconnect-timeout')[0].value;
let pingInterval = container.getElementsByClassName('member-spec__ping-interval')[0].value;

let spec = {};
if (credentials.length > 0) {
spec.credentials = credentials;
}
if (idleTimeout.length > 0) {
spec.idle_timeout = idleTimeout;
}
if (reconnectTimeout.length > 0) {
spec.reconnect_timeout = reconnectTimeout;
}
if (pingInterval.length > 0) {
spec.ping_interval = pingInterval;
}

await controlApi.createMember(roomId, memberId, spec);
});
},

Expand Down Expand Up @@ -546,16 +564,15 @@ const controlApi = {
}
},

createMember: async function(roomId, memberId, credentials) {
createMember: async function(roomId, memberId, spec) {
spec.kind = 'Member';
spec.pipeline = {};

try {
await axios({
method: 'post',
url: controlUrl + roomId + '/' + memberId,
data: {
kind: 'Member',
credentials: credentials,
pipeline: {}
}
data: spec
});
} catch (e) {
alert(JSON.stringify(e.response.data));
Expand Down
5 changes: 5 additions & 0 deletions jason/e2e-demo/video-call.html
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,11 @@
<input class="control-debug__id_room" placeholder="Room ID">
<input class="control-debug__id_member" placeholder="Member ID">
<input class="member-spec__credentials" placeholder="Credentials">
<br>
<input class="member-spec__idle-timeout" placeholder="IDLE timeout">
<input class="member-spec__reconnect-timeout" placeholder="Reconnect timeout">
<input class="member-spec__ping-interval" placeholder="Ping interval">


<button class="control-debug__execute">Execute</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions mock/control-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ actix-cors = "0.2"
actix-web = "2.0"
clap = "2.33"
dotenv = "0.15"
humantime-serde = "1.0"
tonic = "0.1"
medea-control-api-proto = { path = "../../proto/control-api" }
protobuf = "2.11"
Expand Down
29 changes: 28 additions & 1 deletion mock/control-api/src/api/member.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! `Member` element related methods and entities.

use std::collections::HashMap;
use std::{collections::HashMap, convert::TryInto as _, time::Duration};

use medea_control_api_proto::grpc::api as proto;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -33,6 +33,23 @@ pub struct Member {
/// URL to which `OnLeave` Control API callback will be sent.
#[serde(skip_serializing_if = "Option::is_none")]
on_leave: Option<String>,

/// [`Duration`], after which remote RPC client will be considered idle if
/// no heartbeat messages received.
#[serde(default)]
#[serde(with = "humantime_serde")]
idle_timeout: Option<Duration>,

/// [`Duration`], after which the server deletes the client session if
/// the remote RPC client does not reconnect after it is idle.
#[serde(default)]
#[serde(with = "humantime_serde")]
reconnect_timeout: Option<Duration>,

/// Interval of sending `Ping`s from the server to the client.
#[serde(default)]
#[serde(with = "humantime_serde")]
ping_interval: Option<Duration>,
}

impl Member {
Expand All @@ -51,6 +68,9 @@ impl Member {
credentials: self.credentials.unwrap_or_default(),
on_join: self.on_join.unwrap_or_default(),
on_leave: self.on_leave.unwrap_or_default(),
idle_timeout: self.idle_timeout.map(Into::into),
reconnect_timeout: self.reconnect_timeout.map(Into::into),
ping_interval: self.ping_interval.map(Into::into),
}
}

Expand All @@ -77,6 +97,13 @@ impl From<proto::Member> for Member {
credentials: Some(proto.credentials),
on_join: Some(proto.on_join).filter(|s| !s.is_empty()),
on_leave: Some(proto.on_leave).filter(|s| !s.is_empty()),
idle_timeout: proto.idle_timeout.map(|dur| dur.try_into().unwrap()),
reconnect_timeout: proto
.reconnect_timeout
.map(|dur| dur.try_into().unwrap()),
ping_interval: proto
.ping_interval
.map(|dur| dur.try_into().unwrap()),
}
}
}
3 changes: 2 additions & 1 deletion proto/control-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ categories = ["api-bindings", "network-programming"]

[features]
default = ["grpc"]
grpc = ["prost", "tonic-build", "tonic"]
grpc = ["prost", "tonic-build", "tonic", "prost-types"]
evdokimovs marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
prost = { version = "0.6", optional = true }
tonic = { version = "0.1", optional = true }
prost-types = { version = "0.6", optional = true }
evdokimovs marked this conversation as resolved.
Show resolved Hide resolved

[build-dependencies]
tonic-build = { version = "0.1", optional = true}
10 changes: 10 additions & 0 deletions proto/control-api/src/grpc/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ syntax = "proto3";

package api;

import "google/protobuf/duration.proto";
evdokimovs marked this conversation as resolved.
Show resolved Hide resolved

// Media server's Control API service.
service ControlApi {
// Creates new Element with a given ID.
Expand Down Expand Up @@ -142,6 +144,14 @@ message Member {
string credentials = 4;
// Pipeline of this Member.
map<string, Member.Element> pipeline = 5;
// Duration, after which remote RPC client will be considered idle if no
// heartbeat messages received.
google.protobuf.Duration idle_timeout = 6;
evdokimovs marked this conversation as resolved.
Show resolved Hide resolved
// Duration, after which the server deletes the client session if
// the remote RPC client does not reconnect after it is idle.
google.protobuf.Duration reconnect_timeout = 7;
// Interval of sending pings from the server to the client.
google.protobuf.Duration ping_interval = 8;

// Elements which Member's pipeline can contain.
message Element {
Expand Down
11 changes: 11 additions & 0 deletions proto/control-api/src/grpc/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,17 @@ pub struct Member {
/// Pipeline of this Member.
#[prost(map="string, message", tag="5")]
pub pipeline: ::std::collections::HashMap<std::string::String, member::Element>,
/// Duration, after which remote RPC client will be considered idle if no
/// heartbeat messages received.
#[prost(message, optional, tag="6")]
pub idle_timeout: ::std::option::Option<::prost_types::Duration>,
/// Duration, after which the server deletes the client session if
/// the remote RPC client does not reconnect after it is idle.
#[prost(message, optional, tag="7")]
pub reconnect_timeout: ::std::option::Option<::prost_types::Duration>,
/// Interval of sending pings from the server to the client.
#[prost(message, optional, tag="8")]
pub ping_interval: ::std::option::Option<::prost_types::Duration>,
}
pub mod member {
/// Elements which Member's pipeline can contain.
Expand Down
15 changes: 13 additions & 2 deletions src/api/client/rpc_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! [`RpcConnection`]: crate::api::client::rpc_connection::RpcConnection

use std::fmt;
use std::{fmt, time::Duration};

use actix::Message;
use derive_more::{From, Into};
Expand Down Expand Up @@ -60,9 +60,20 @@ pub trait RpcConnection: fmt::Debug + Send {
-> LocalBoxFuture<'static, Result<(), ()>>;
}

/// Settings for the [`WsSession`].
#[derive(Clone, Copy, Debug)]
pub struct RpcConnectionSettings {
/// Duration, after which [`WsSession`] will be considered idle if no
/// heartbeat messages received.
pub idle_timeout: Duration,

/// Interval of sending `Ping`s from the server to the client.
pub ping_interval: Duration,
}

/// Signal for authorizing new [`RpcConnection`] before establishing.
#[derive(Debug, Message)]
#[rtype(result = "Result<(), AuthorizationError>")]
#[rtype(result = "Result<RpcConnectionSettings, AuthorizationError>")]
pub struct Authorize {
/// ID of [`Member`] to authorize [`RpcConnection`] for.
///
Expand Down
Loading