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 all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `Member`'s Client API RPC settings ([#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
9 changes: 9 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,28 @@
# Duration, after which remote RPC client will be considered idle if no
# heartbeat messages received.
#
# It applies to all related pipelines as default value, but can be overridden
# for each specific case via Control API.
#
# 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.
#
# It applies to all related pipelines as default value, but can be overridden
# for each specific case via Control API.
#
# Env var: MEDEA_RPC__RECONNECT_TIMEOUT
# Default:
# reconnect_timeout = "10s"

# Interval between pings that server sends to clients.
#
# It applies to all related pipelines as default value, but can be overridden
# for each specific case via Control API.
#
# Env var: MEDEA_RPC__PING_INTERVAL
# Default:
# ping_interval = "3s"
Expand Down
14 changes: 13 additions & 1 deletion 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"
# Timeout of receiving heartbeat messages from the member via WebSocket.
# Once reached, the member is considered being idle.
idle_timeout: 1m
# Timeout of the member reconnecting via WebSocket.
# Once reached, the member is considered disconnected.
reconnect_timeout: 3m
# Interval of sending pings from media server to the member via WebSocket.
ping_interval: 10s
pipeline:
# Media element which is able to receive media data from client via WebRTC.
publish:
Expand Down Expand Up @@ -780,7 +788,11 @@ message Room {
message Member {
optional string on_join = 1;
optional string on_leave = 2;
map<string, Member.Element> pipeline = 3;
optional string credentials = 3;
optional uint64 idle_timeout = 4;
optional uint64 reconnect_timeout = 5;
optional uint64 ping_interval = 6;
map<string, Member.Element> pipeline = 7;

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
5 changes: 3 additions & 2 deletions mock/control-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ publish = false

[dependencies]
actix = "0.9"
actix-rt = "1.0"
actix-cors = "0.2"
actix-rt = "1.0"
actix-web = "2.0"
clap = "2.33"
dotenv = "0.15"
tonic = "0.1"
humantime-serde = "1.0"
medea-control-api-proto = { path = "../../proto/control-api" }
protobuf = "2.11"
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -26,3 +26,4 @@ slog-envlogger = "2.2"
slog-scope = "4.3"
slog-stdlog = "4.0"
slog-term = "2.5"
tonic = "0.1"
26 changes: 25 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,20 @@ pub struct Member {
/// URL to which `OnLeave` Control API callback will be sent.
#[serde(skip_serializing_if = "Option::is_none")]
on_leave: Option<String>,

/// Timeout of receiving heartbeat messages from the `Member` via Client
/// API. Once reached, the `Member` is considered being idle.
#[serde(default, with = "humantime_serde")]
idle_timeout: Option<Duration>,

/// Timeout of the `Member` reconnecting via Client API.
/// Once reached, the `Member` is considered disconnected.
#[serde(default, with = "humantime_serde")]
reconnect_timeout: Option<Duration>,

/// Interval of sending pings from Medea to the `Member` via Client API.
#[serde(default, with = "humantime_serde")]
ping_interval: Option<Duration>,
}

impl Member {
Expand All @@ -51,6 +65,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 +94,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()),
}
}
}
5 changes: 3 additions & 2 deletions 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", "prost-types", "tonic", "tonic-build"]

[dependencies]
prost = { version = "0.6", optional = true }
prost-types = { version = "0.6", optional = true }
tonic = { version = "0.1", optional = true }

[build-dependencies]
tonic-build = { version = "0.1", optional = true}
tonic-build = { version = "0.1", optional = true }
18 changes: 15 additions & 3 deletions proto/control-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ mod grpc {
.build_client(true)
.build_server(true)
.compile(&grpc_spec_files, &[GRPC_DIR.to_string()])?;

// Remove empty `google.protobuf.rs` file generated by
// `prost-build`. This file doesn't affect to any
// functionality. It's generated only because of
// `prost-build` bug.
//
// Read instrumentisto/medea#95, hyperium/tonic#314 and
// danburkert/prost#228 for more info.
fs::remove_file(format!("{}/google.protobuf.rs", GRPC_DIR))
.expect(
"`google.protobuf.rs` file isn't generated. This \
is good news, because hyperium/tonic#314 issue \
was probably really fixed. Check it and if so, \
then just remove this line of code.",
);
break;
} else {
panic!("{}", e);
Expand Down Expand Up @@ -97,9 +112,6 @@ mod grpc {
self.0
.iter()
.map(|filename| format!("{}/{}.rs", GRPC_DIR, filename))
.chain(self.0.iter().map(|filename| {
format!("{}/{}_grpc.rs", GRPC_DIR, filename)
}))
.collect()
}
}
Expand Down
12 changes: 11 additions & 1 deletion 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";

// Media server's Control API service.
service ControlApi {
// Creates new Element with a given ID.
Expand Down Expand Up @@ -140,8 +142,16 @@ message Member {
string on_leave = 3;
// Credentials of the Member to authorize via Client API with.
string credentials = 4;
// Timeout of receiving heartbeat messages from the Member via Client API.
// Once reached, the Member is considered being idle.
google.protobuf.Duration idle_timeout = 5;
// Timeout of the Member reconnecting via Client API.
// Once reached, the Member is considered disconnected.
google.protobuf.Duration reconnect_timeout = 6;
// Interval of sending pings from a media server to the Member via Client API.
google.protobuf.Duration ping_interval = 7;
// Pipeline of this Member.
map<string, Member.Element> pipeline = 5;
map<string, Member.Element> pipeline = 8;

// Elements which Member's pipeline can contain.
message Element {
Expand Down
Loading