mirror of
https://github.com/actix/examples
synced 2024-11-23 14:31:07 +01:00
Merge pull request #863 from c-git/add-client
Move client file from old echo example to actorless
This commit is contained in:
commit
4e35739c1c
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -8916,10 +8916,12 @@ dependencies = [
|
||||
"actix-files",
|
||||
"actix-web",
|
||||
"actix-ws",
|
||||
"awc",
|
||||
"env_logger",
|
||||
"futures-util",
|
||||
"log",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3,11 +3,21 @@ name = "websockets-echo-actorless-example"
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "websocket-server"
|
||||
path = "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "websocket-client"
|
||||
path = "src/client.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-files.workspace = true
|
||||
actix-web.workspace = true
|
||||
actix-ws.workspace = true
|
||||
awc.workspace = true
|
||||
env_logger.workspace = true
|
||||
futures-util.workspace = true
|
||||
futures-util = { workspace = true, features = ["sink"] }
|
||||
log.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "time", "macros"] }
|
||||
tokio-stream.workspace = true
|
||||
|
@ -8,7 +8,7 @@ Simple echo websocket server using [`actix-ws`].
|
||||
|
||||
```sh
|
||||
cd websockets/echo-actorless
|
||||
cargo run
|
||||
cargo run --bin websocket-server
|
||||
# starting HTTP server at http://localhost:8080
|
||||
```
|
||||
|
||||
@ -16,6 +16,13 @@ cargo run
|
||||
|
||||
Go to <http://localhost:8080> in a browser.
|
||||
|
||||
### rust client
|
||||
|
||||
```sh
|
||||
cd websockets/echo-actorless
|
||||
cargo run --bin websocket-client
|
||||
```
|
||||
|
||||
### CLI Client
|
||||
|
||||
```sh
|
||||
|
72
websockets/echo-actorless/src/client.rs
Normal file
72
websockets/echo-actorless/src/client.rs
Normal file
@ -0,0 +1,72 @@
|
||||
//! Simple websocket client.
|
||||
|
||||
use std::{io, thread};
|
||||
|
||||
use actix_web::web::Bytes;
|
||||
use awc::ws;
|
||||
use futures_util::{SinkExt as _, StreamExt as _};
|
||||
use tokio::{select, sync::mpsc};
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() {
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
|
||||
log::info!("starting echo WebSocket client");
|
||||
|
||||
let (cmd_tx, cmd_rx) = mpsc::unbounded_channel();
|
||||
let mut cmd_rx = UnboundedReceiverStream::new(cmd_rx);
|
||||
|
||||
// run blocking terminal input reader on separate thread
|
||||
let input_thread = thread::spawn(move || loop {
|
||||
let mut cmd = String::with_capacity(32);
|
||||
|
||||
if io::stdin().read_line(&mut cmd).is_err() {
|
||||
log::error!("error reading line");
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_tx.send(cmd).unwrap();
|
||||
});
|
||||
|
||||
let (res, mut ws) = awc::Client::new()
|
||||
.ws("ws://127.0.0.1:8080/ws")
|
||||
.connect()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
log::debug!("response: {res:?}");
|
||||
log::info!("connected; server will echo messages sent");
|
||||
|
||||
loop {
|
||||
select! {
|
||||
Some(msg) = ws.next() => {
|
||||
match msg {
|
||||
Ok(ws::Frame::Text(txt)) => {
|
||||
// log echoed messages from server
|
||||
log::info!("Server: {txt:?}")
|
||||
}
|
||||
|
||||
Ok(ws::Frame::Ping(_)) => {
|
||||
// respond to ping probes
|
||||
ws.send(ws::Message::Pong(Bytes::new())).await.unwrap();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Some(cmd) = cmd_rx.next() => {
|
||||
if cmd.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
ws.send(ws::Message::Text(cmd.into())).await.unwrap();
|
||||
}
|
||||
|
||||
else => break
|
||||
}
|
||||
}
|
||||
|
||||
input_thread.join().unwrap();
|
||||
}
|
@ -22,4 +22,4 @@ env_logger.workspace = true
|
||||
futures-util = { workspace = true, features = ["sink"] }
|
||||
log.workspace = true
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
tokio-stream = "0.1.8"
|
||||
tokio-stream.workspace = true
|
||||
|
@ -1,72 +0,0 @@
|
||||
//! Simple websocket client.
|
||||
|
||||
use std::{io, thread};
|
||||
|
||||
use actix_web::web::Bytes;
|
||||
use awc::ws;
|
||||
use futures_util::{SinkExt as _, StreamExt as _};
|
||||
use tokio::{select, sync::mpsc};
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() {
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
|
||||
log::info!("starting echo WebSocket client");
|
||||
|
||||
let (cmd_tx, cmd_rx) = mpsc::unbounded_channel();
|
||||
let mut cmd_rx = UnboundedReceiverStream::new(cmd_rx);
|
||||
|
||||
// run blocking terminal input reader on separate thread
|
||||
let input_thread = thread::spawn(move || loop {
|
||||
let mut cmd = String::with_capacity(32);
|
||||
|
||||
if io::stdin().read_line(&mut cmd).is_err() {
|
||||
log::error!("error reading line");
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_tx.send(cmd).unwrap();
|
||||
});
|
||||
|
||||
let (res, mut ws) = awc::Client::new()
|
||||
.ws("ws://127.0.0.1:8080/ws")
|
||||
.connect()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
log::debug!("response: {res:?}");
|
||||
log::info!("connected; server will echo messages sent");
|
||||
|
||||
loop {
|
||||
select! {
|
||||
Some(msg) = ws.next() => {
|
||||
match msg {
|
||||
Ok(ws::Frame::Text(txt)) => {
|
||||
// log echoed messages from server
|
||||
log::info!("Server: {txt:?}")
|
||||
}
|
||||
|
||||
Ok(ws::Frame::Ping(_)) => {
|
||||
// respond to ping probes
|
||||
ws.send(ws::Message::Pong(Bytes::new())).await.unwrap();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Some(cmd) = cmd_rx.next() => {
|
||||
if cmd.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
ws.send(ws::Message::Text(cmd.into())).await.unwrap();
|
||||
}
|
||||
|
||||
else => break
|
||||
}
|
||||
}
|
||||
|
||||
input_thread.join().unwrap();
|
||||
}
|
1
websockets/echo/src/client.rs
Symbolic link
1
websockets/echo/src/client.rs
Symbolic link
@ -0,0 +1 @@
|
||||
../../echo-actorless/src/client.rs
|
Loading…
Reference in New Issue
Block a user