From 6846e96f86e9e6fdd6ca8f7128201f8b9057977c Mon Sep 17 00:00:00 2001 From: Nikos Papadakis Date: Mon, 5 Feb 2024 01:25:37 +0200 Subject: [PATCH] socket --- Cargo.lock | 68 +++++++++++++++++++++- agent/Cargo.toml | 1 + agent/src/channels/mod.rs | 6 ++ agent/src/main.rs | 5 ++ app/lib/prymn_web/channels/agent_socket.ex | 53 +++++++++++++++++ app/lib/prymn_web/endpoint.ex | 4 ++ 6 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 agent/src/channels/mod.rs create mode 100644 app/lib/prymn_web/channels/agent_socket.ex diff --git a/Cargo.lock b/Cargo.lock index eb64435..dc94000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ "base64", "bytes", "futures", - "http", + "http 0.2.11", "memchr", "nkeys", "nuid", @@ -427,6 +427,23 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + [[package]] name = "idna" version = "0.5.0" @@ -717,6 +734,7 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", + "tokio-tungstenite", "tokio-util", "tracing", "tracing-subscriber", @@ -996,6 +1014,17 @@ dependencies = [ "syn", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.8" @@ -1255,6 +1284,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -1326,6 +1367,25 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.0.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -1370,6 +1430,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "valuable" version = "0.1.0" diff --git a/agent/Cargo.toml b/agent/Cargo.toml index a4d9053..6c80ade 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -17,6 +17,7 @@ sysinfo = { version = "0.30.5", default-features = false } thiserror = "1.0.56" tokio = { version = "1.35.1", features = ["full"] } tokio-stream = { version = "0.1.14", default-features = false } +tokio-tungstenite = "0.21.0" tokio-util = { version = "0.7.10", features = ["codec"] } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["fmt"] } diff --git a/agent/src/channels/mod.rs b/agent/src/channels/mod.rs new file mode 100644 index 0000000..3eeef5e --- /dev/null +++ b/agent/src/channels/mod.rs @@ -0,0 +1,6 @@ +pub async fn testchannel() -> anyhow::Result<()> { + let (ws_stream, _) = + tokio_tungstenite::connect_async("ws://localhost:4000/agent/websocket?vsn=2.0.0").await?; + + Ok(()) +} diff --git a/agent/src/main.rs b/agent/src/main.rs index ee93cb7..2782f77 100644 --- a/agent/src/main.rs +++ b/agent/src/main.rs @@ -1,5 +1,8 @@ use tokio::signal::ctrl_c; +use crate::channels::testchannel; + +mod channels; mod health; mod messaging; mod pty; @@ -29,6 +32,8 @@ async fn run() -> anyhow::Result<()> { crate::messaging::init_services(client).await?; tracing::info!("initialized services"); + testchannel().await; + ctrl_c().await?; Ok(()) } diff --git a/app/lib/prymn_web/channels/agent_socket.ex b/app/lib/prymn_web/channels/agent_socket.ex new file mode 100644 index 0000000..bda644b --- /dev/null +++ b/app/lib/prymn_web/channels/agent_socket.ex @@ -0,0 +1,53 @@ +defmodule PrymnWeb.AgentSocket do + use Phoenix.Socket + + # A Socket handler + # + # It's possible to control the websocket connection and + # assign values that can be accessed by your channel topics. + + ## Channels + # Uncomment the following line to define a "room:*" topic + # pointing to the `PrymnWeb.RoomChannel`: + # + # channel "room:*", PrymnWeb.RoomChannel + # + # To create a channel file, use the mix task: + # + # mix phx.gen.channel Room + # + # See the [`Channels guide`](https://hexdocs.pm/phoenix/channels.html) + # for further details. + + # Socket params are passed from the client and can + # be used to verify and authenticate a user. After + # verification, you can put default assigns into + # the socket that will be set for all channels, ie + # + # {:ok, assign(socket, :user_id, verified_user_id)} + # + # To deny connection, return `:error` or `{:error, term}`. To control the + # response the client receives in that case, [define an error handler in the + # websocket + # configuration](https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#socket/3-websocket-configuration). + # + # See `Phoenix.Token` documentation for examples in + # performing token verification on connect. + @impl true + def connect(_params, socket, _connect_info) do + {:ok, socket} + end + + # Socket id's are topics that allow you to identify all sockets for a given user: + # + # def id(socket), do: "user_socket:#{socket.assigns.user_id}" + # + # Would allow you to broadcast a "disconnect" event and terminate + # all active sockets and channels for a given user: + # + # PrymnWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) + # + # Returning `nil` makes this socket anonymous. + @impl true + def id(_socket), do: nil +end diff --git a/app/lib/prymn_web/endpoint.ex b/app/lib/prymn_web/endpoint.ex index 1f4557d..f0c9304 100644 --- a/app/lib/prymn_web/endpoint.ex +++ b/app/lib/prymn_web/endpoint.ex @@ -13,6 +13,10 @@ defmodule PrymnWeb.Endpoint do socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]] + socket "/agent", PrymnWeb.AgentSocket, + websocket: true, + longpoll: false + # Serve at "/" the static files from "priv/static" directory. # # You should set gzip to true if you are running phx.digest