ply_engine/net/
websocket.rs1#[cfg(target_arch = "wasm32")]
2use sapp_jsutils::JsObject;
3
4pub struct WsConfig {
6 pub(crate) headers: Vec<(String, String)>,
7 pub(crate) insecure: bool,
8}
9
10impl WsConfig {
11 pub(crate) fn new() -> Self {
12 Self {
13 headers: Vec::new(),
14 insecure: false,
15 }
16 }
17
18 pub fn header(&mut self, key: &str, value: &str) -> &mut Self {
20 self.headers.push((key.to_owned(), value.to_owned()));
21 self
22 }
23
24 pub fn insecure(&mut self) -> &mut Self {
27 self.insecure = true;
28 self
29 }
30}
31
32#[derive(Debug, Clone)]
34pub enum WsMessage {
35 Connected,
37 Text(String),
39 Binary(Vec<u8>),
41 Error(String),
43 Closed,
45}
46
47#[cfg(not(target_arch = "wasm32"))]
49pub(crate) enum OutgoingWsMessage {
50 Text(String),
51 Binary(Vec<u8>),
52 Close,
53}
54
55pub struct WebSocket {
59 pub(crate) id: u64,
60}
61
62impl WebSocket {
63 pub fn send(&self, data: &[u8]) {
65 let mgr = super::NET_MANAGER.lock().unwrap();
66 if let Some(entry) = mgr.websockets.get(&self.id) {
67 entry.state.send_binary(data);
68 }
69 }
70
71 pub fn send_text(&self, text: &str) {
73 let mgr = super::NET_MANAGER.lock().unwrap();
74 if let Some(entry) = mgr.websockets.get(&self.id) {
75 entry.state.send_text(text);
76 }
77 }
78
79 pub fn recv(&self) -> Option<WsMessage> {
84 let mut mgr = super::NET_MANAGER.lock().unwrap();
85 let entry = mgr.websockets.get_mut(&self.id)?;
86 entry.frames_not_accessed = 0;
87 entry.state.try_recv()
88 }
89
90 pub fn close(self) {
92 let mut mgr = super::NET_MANAGER.lock().unwrap();
93 if let Some(entry) = mgr.websockets.get(&self.id) {
94 entry.state.close();
95 }
96 mgr.websockets.remove(&self.id);
97 }
98}
99
100#[cfg(not(target_arch = "wasm32"))]
102pub(crate) struct WebSocketState {
103 pub tx: tokio::sync::mpsc::UnboundedSender<OutgoingWsMessage>,
104 pub rx: std::sync::mpsc::Receiver<WsMessage>,
105 pub _runtime: tokio::runtime::Runtime,
106}
107
108#[cfg(not(target_arch = "wasm32"))]
109impl WebSocketState {
110 pub fn send_binary(&self, data: &[u8]) {
111 let _ = self.tx.send(OutgoingWsMessage::Binary(data.to_vec()));
112 }
113
114 pub fn send_text(&self, text: &str) {
115 let _ = self.tx.send(OutgoingWsMessage::Text(text.to_owned()));
116 }
117
118 pub fn try_recv(&self) -> Option<WsMessage> {
119 self.rx.try_recv().ok()
120 }
121
122 pub fn close(&self) {
123 let _ = self.tx.send(OutgoingWsMessage::Close);
124 }
125
126 pub fn is_disconnected(&self) -> bool {
127 self.tx.is_closed()
128 }
129}
130
131#[cfg(target_arch = "wasm32")]
133pub(crate) struct WebSocketState {
134 pub socket_id: i32,
136}
137
138#[cfg(target_arch = "wasm32")]
139impl WebSocketState {
140 pub fn send_binary(&self, data: &[u8]) {
141 unsafe {
142 ply_net_ws_send_binary(self.socket_id, JsObject::buffer(data));
143 }
144 }
145
146 pub fn send_text(&self, text: &str) {
147 unsafe {
148 ply_net_ws_send_text(self.socket_id, JsObject::string(text));
149 }
150 }
151
152 pub fn try_recv(&self) -> Option<WsMessage> {
153 let js_obj = unsafe { ply_net_ws_try_recv(self.socket_id) };
154 if js_obj.is_nil() {
155 return None;
156 }
157
158 let type_id = js_obj.field_u32("type");
159 match type_id {
160 0 => Some(WsMessage::Connected), 1 => { let mut buf = Vec::new();
163 js_obj.field("data").to_byte_buffer(&mut buf);
164 Some(WsMessage::Binary(buf))
165 }
166 2 => { let mut text = String::new();
168 js_obj.field("data").to_string(&mut text);
169 Some(WsMessage::Text(text))
170 }
171 3 => { let mut err = String::new();
173 js_obj.field("data").to_string(&mut err);
174 Some(WsMessage::Error(err))
175 }
176 4 => Some(WsMessage::Closed), _ => None,
178 }
179 }
180
181 pub fn close(&self) {
182 unsafe {
183 ply_net_ws_close(self.socket_id);
184 }
185 }
186
187 pub fn is_disconnected(&self) -> bool {
190 false
193 }
194}
195
196#[cfg(target_arch = "wasm32")]
198extern "C" {
199 pub(crate) fn ply_net_ws_connect(socket_id: i32, addr: JsObject);
200 fn ply_net_ws_send_binary(socket_id: i32, data: JsObject);
201 fn ply_net_ws_send_text(socket_id: i32, text: JsObject);
202 fn ply_net_ws_close(socket_id: i32);
203 fn ply_net_ws_try_recv(socket_id: i32) -> JsObject;
204}