1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
pub mod server;
use iced::futures;
use iced::task::{Never, Sipper, sipper};
use iced::widget::text;
use futures::channel::mpsc;
use futures::sink::SinkExt;
use futures::stream::StreamExt;
use async_tungstenite::tungstenite;
use std::fmt;
pub fn connect() -> impl Sipper<Never, Event> {
sipper(|mut output| async move {
loop {
const ECHO_SERVER: &str = "ws://127.0.0.1:3030";
let (mut websocket, mut input) =
match async_tungstenite::tokio::connect_async(ECHO_SERVER).await
{
Ok((websocket, _)) => {
let (sender, receiver) = mpsc::channel(100);
output.send(Event::Connected(Connection(sender))).await;
(websocket.fuse(), receiver)
}
Err(_) => {
tokio::time::sleep(tokio::time::Duration::from_secs(1))
.await;
output.send(Event::Disconnected).await;
continue;
}
};
loop {
futures::select! {
received = websocket.select_next_some() => {
match received {
Ok(tungstenite::Message::Text(message)) => {
output.send(Event::MessageReceived(Message::User(message))).await;
}
Err(_) => {
output.send(Event::Disconnected).await;
break;
}
Ok(_) => {},
}
}
message = input.select_next_some() => {
let result = websocket.send(tungstenite::Message::Text(message.to_string())).await;
if result.is_err() {
output.send(Event::Disconnected).await;
}
}
}
}
}
})
}
#[derive(Debug, Clone)]
pub enum Event {
Connected(Connection),
Disconnected,
MessageReceived(Message),
}
#[derive(Debug, Clone)]
pub struct Connection(mpsc::Sender<Message>);
impl Connection {
pub fn send(&mut self, message: Message) {
self.0
.try_send(message)
.expect("Send message to echo server");
}
}
#[derive(Debug, Clone)]
pub enum Message {
Connected,
Disconnected,
User(String),
}
impl Message {
pub fn new(message: &str) -> Option<Self> {
if message.is_empty() {
None
} else {
Some(Self::User(message.to_string()))
}
}
pub fn connected() -> Self {
Message::Connected
}
pub fn disconnected() -> Self {
Message::Disconnected
}
pub fn as_str(&self) -> &str {
match self {
Message::Connected => "Connected successfully!",
Message::Disconnected => "Connection lost... Retrying...",
Message::User(message) => message.as_str(),
}
}
}
impl fmt::Display for Message {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl<'a> text::IntoFragment<'a> for &'a Message {
fn into_fragment(self) -> text::Fragment<'a> {
text::Fragment::Borrowed(self.as_str())
}
}
|