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 21 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 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.
#
# 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.
#
# 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.
#
# 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"
# Timeout of receiving heartbeat messages from the Member via Client API.
# Once reached, the Member is considered being idle.
idle_timeout: 1m
# Timeout of the Member reconnecting via Client API.
# Once reached, the Member is considered disconnected.
reconnect_timeout: 3m
# Interval of sending pings from a media server to the Member via Client API.
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
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"
30 changes: 29 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,24 @@ 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)]
#[serde(with = "humantime_serde")]
idle_timeout: Option<Duration>,

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

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

impl Member {
Expand All @@ -51,6 +69,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 +98,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 }
evdokimovs marked this conversation as resolved.
Show resolved Hide resolved
tonic = { version = "0.1", optional = true }

[build-dependencies]
tonic-build = { version = "0.1", optional = true}
tonic-build = { version = "0.1", optional = true }
17 changes: 14 additions & 3 deletions proto/control-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ 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 affects to the any
// functional. It's generated because '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 maybe hyperium/tonic#314 \
issue was really fixed. Check it and if it is \
then just remove this line of code.",
);
break;
} else {
panic!("{}", e);
Expand Down Expand Up @@ -97,9 +111,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";
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 @@ -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