Concept is proven, though it won't work for streaming
parent
e3aa61bb9a
commit
0cc61796c0
|
@ -1,4 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "ptth"
|
name = "ptth"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["_"]
|
authors = ["_"]
|
||||||
|
@ -7,7 +8,9 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
futures = "0.3.7"
|
futures = "0.3.7"
|
||||||
hyper = "0.13.8"
|
hyper = "0.13.8"
|
||||||
reqwest = "0.10.8"
|
reqwest = "0.10.8"
|
||||||
tokio = { version = "0.2", features = ["full"] }
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
|
ulid = "0.4.1"
|
||||||
|
|
|
@ -26,7 +26,10 @@ use ptth::watcher::Watchers;
|
||||||
#[derive (Clone)]
|
#[derive (Clone)]
|
||||||
enum Message {
|
enum Message {
|
||||||
Meow,
|
Meow,
|
||||||
HttpRequest (String),
|
//HttpRequestRequest (String),
|
||||||
|
HttpRequestResponse (String),
|
||||||
|
// HttpResponseRequest (String),
|
||||||
|
HttpResponseResponse (String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Default)]
|
#[derive (Default)]
|
||||||
|
@ -65,26 +68,84 @@ async fn handle_wake (state: Arc <ServerState>, watcher_code: String)
|
||||||
async fn handle_http_listen (state: Arc <ServerState>, watcher_code: String)
|
async fn handle_http_listen (state: Arc <ServerState>, watcher_code: String)
|
||||||
-> Response <Body>
|
-> Response <Body>
|
||||||
{
|
{
|
||||||
|
println! ("Step 1");
|
||||||
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
match Watchers::long_poll (state.watchers.clone (), watcher_code).await {
|
||||||
Some (Message::HttpRequest (uri)) => status_reply (StatusCode::OK, uri),
|
Some (Message::HttpRequestResponse (uri)) => {
|
||||||
|
println! ("Step 3");
|
||||||
|
status_reply (StatusCode::OK, uri)
|
||||||
|
},
|
||||||
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
|
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "no\n"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_http_response (
|
||||||
|
state: Arc <ServerState>,
|
||||||
|
req_id: String,
|
||||||
|
response: String
|
||||||
|
)
|
||||||
|
-> Response <Body>
|
||||||
|
{
|
||||||
|
println! ("Step 6");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut watchers = state.watchers.lock ().await;
|
||||||
|
|
||||||
|
println! ("Step 7");
|
||||||
|
if ! watchers.wake_one (Message::HttpResponseResponse (response), &req_id)
|
||||||
|
{
|
||||||
|
println! ("Step 8");
|
||||||
|
return status_reply (StatusCode::BAD_REQUEST, "A bad thing happened.\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println! ("Step 8");
|
||||||
|
status_reply (StatusCode::OK, "ok\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_http_request (
|
async fn handle_http_request (
|
||||||
state: Arc <ServerState>,
|
state: Arc <ServerState>,
|
||||||
watcher_code: String,
|
watcher_code: String,
|
||||||
uri: String
|
uri: String
|
||||||
)
|
)
|
||||||
-> Response <Body>
|
-> Response <Body>
|
||||||
|
{
|
||||||
|
let req_id = format! ("client_{}", ulid::Ulid::new ().to_string ());
|
||||||
|
|
||||||
|
println! ("Step 2 {}", req_id);
|
||||||
|
|
||||||
|
let (s, r) = oneshot::channel ();
|
||||||
|
let timeout = Duration::from_secs (5);
|
||||||
|
|
||||||
|
let id_2 = req_id.clone ();
|
||||||
|
{
|
||||||
|
let mut that = state.watchers.lock ().await;
|
||||||
|
that.add_watcher_with_id (s, id_2)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokio::spawn (async move {
|
||||||
{
|
{
|
||||||
let mut watchers = state.watchers.lock ().await;
|
let mut watchers = state.watchers.lock ().await;
|
||||||
|
|
||||||
if watchers.wake_one (Message::HttpRequest (uri), &watcher_code) {
|
println! ("Step 3");
|
||||||
status_reply (StatusCode::OK, "ok\n")
|
if ! watchers.wake_one (Message::HttpRequestResponse (req_id.clone ()), &watcher_code) {
|
||||||
|
watchers.remove_watcher (&req_id);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
status_reply (StatusCode::BAD_REQUEST, "no\n")
|
|
||||||
|
delay_for (timeout).await;
|
||||||
|
{
|
||||||
|
let mut that = state.watchers.lock ().await;
|
||||||
|
that.remove_watcher (&req_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
match r.await {
|
||||||
|
Ok (Message::HttpResponseResponse (s)) => {
|
||||||
|
println! ("Step 7");
|
||||||
|
status_reply (StatusCode::OK, s)
|
||||||
|
},
|
||||||
|
_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "server didn't reply in time or somethin'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +210,16 @@ async fn handle_all (req: Request <Body>, state: Arc <ServerState>)
|
||||||
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
|
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if let Some (rest) = prefix_match (path, "/http_response/") {
|
||||||
|
if let Some (idx) = rest.find ('/') {
|
||||||
|
let request_code = &rest [0..idx];
|
||||||
|
let response = &rest [idx + 1..];
|
||||||
|
Ok (handle_http_response (state, request_code.into (), response.into ()).await)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ok (status_reply (StatusCode::BAD_REQUEST, "Bad URI format"))
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
else if let Some (name) = prefix_match (path, "/udp_send/") {
|
else if let Some (name) = prefix_match (path, "/udp_send/") {
|
||||||
Ok (handle_udp_send ().await)
|
Ok (handle_udp_send ().await)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::error::Error;
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use hyper::{
|
use hyper::{
|
||||||
StatusCode,
|
StatusCode,
|
||||||
|
@ -9,7 +12,7 @@ use tokio::fs::File;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main () -> Result <(), Box <dyn Error>> {
|
async fn main () -> Result <(), Box <dyn Error>> {
|
||||||
let client = Client::new ();
|
let client = Arc::new (Client::new ());
|
||||||
|
|
||||||
let path = "/home/user/pictures/bzqcChY.jpg";
|
let path = "/home/user/pictures/bzqcChY.jpg";
|
||||||
|
|
||||||
|
@ -17,11 +20,13 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
||||||
let _uri = Uri::builder ()
|
let _uri = Uri::builder ()
|
||||||
.scheme ("http")
|
.scheme ("http")
|
||||||
.authority ("127.0.0.1:4000")
|
.authority ("127.0.0.1:4000")
|
||||||
.path_and_query ("/listen/alien_wildlands")
|
.path_and_query ("/http_listen/alien_wildlands")
|
||||||
.build ().unwrap ();
|
.build ().unwrap ();
|
||||||
|
|
||||||
let req = client.get ("http://127.0.0.1:4000/http_listen/alien_wildlands");
|
let req_req = client.get ("http://127.0.0.1:4000/http_listen/alien_wildlands");
|
||||||
let response = match req.send ().await {
|
|
||||||
|
println! ("Step 1");
|
||||||
|
let req_resp = match req_req.send ().await {
|
||||||
Err (e) => {
|
Err (e) => {
|
||||||
println! ("Err: {:?}", e);
|
println! ("Err: {:?}", e);
|
||||||
continue;
|
continue;
|
||||||
|
@ -29,15 +34,38 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
||||||
Ok (r) => r,
|
Ok (r) => r,
|
||||||
};
|
};
|
||||||
|
|
||||||
if response.status () != StatusCode::OK {
|
if req_resp.status () != StatusCode::OK {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = response.bytes ().await?;
|
println! ("Step 3");
|
||||||
let body = std::str::from_utf8 (&body)?;
|
|
||||||
|
let body = req_resp.bytes ().await?;
|
||||||
|
let body = String::from (std::str::from_utf8 (&body)?);
|
||||||
|
|
||||||
println! ("Client requested {}", body);
|
println! ("Client requested {}", body);
|
||||||
}
|
|
||||||
|
|
||||||
Ok (())
|
println! ("Step 4/5");
|
||||||
|
let payload = String::from ("Ha ha hue hue it worked.");
|
||||||
|
|
||||||
|
println! ("Step 6");
|
||||||
|
let client = client.clone ();
|
||||||
|
tokio::spawn (async move {
|
||||||
|
let resp_req = Uri::builder ()
|
||||||
|
.scheme ("http")
|
||||||
|
.authority ("127.0.0.1:4000")
|
||||||
|
.path_and_query ("/listen/alien_wildlands")
|
||||||
|
.build ().unwrap ();
|
||||||
|
|
||||||
|
let resp_req = client.get (&format! ("http://127.0.0.1:4000/http_response/{}/{}", body, payload));
|
||||||
|
|
||||||
|
println! ("Step 6");
|
||||||
|
match resp_req.send ().await {
|
||||||
|
Err (e) => {
|
||||||
|
println! ("Err: {:?}", e);
|
||||||
|
},
|
||||||
|
Ok (_) => (),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ impl <T: 'static + Clone + Send + Sync> Watchers <T> {
|
||||||
self.senders.insert (id, s);
|
self.senders.insert (id, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_watcher (&mut self, id: String) {
|
pub fn remove_watcher (&mut self, id: &str) {
|
||||||
self.senders.remove (&id);
|
self.senders.remove (id);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
fn wake_all (&mut self, msg: T) {
|
fn wake_all (&mut self, msg: T) {
|
||||||
|
@ -63,7 +63,6 @@ impl <T: 'static + Clone + Send + Sync> Watchers <T> {
|
||||||
println! ("long_poll {}", id);
|
println! ("long_poll {}", id);
|
||||||
|
|
||||||
let (s, r) = oneshot::channel ();
|
let (s, r) = oneshot::channel ();
|
||||||
|
|
||||||
let timeout = Duration::from_secs (5);
|
let timeout = Duration::from_secs (5);
|
||||||
|
|
||||||
let id_2 = id.clone ();
|
let id_2 = id.clone ();
|
||||||
|
@ -75,7 +74,7 @@ impl <T: 'static + Clone + Send + Sync> Watchers <T> {
|
||||||
tokio::spawn (async move {
|
tokio::spawn (async move {
|
||||||
delay_for (timeout).await;
|
delay_for (timeout).await;
|
||||||
let mut that = that.lock ().await;
|
let mut that = that.lock ().await;
|
||||||
that.remove_watcher (id);
|
that.remove_watcher (&id);
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Ok (message) = r.await {
|
if let Ok (message) = r.await {
|
||||||
|
|
Loading…
Reference in New Issue