~starkingdoms/starkingdoms

ref: 9f2fc987783eb8bccb423c5326d4c82de719356c starkingdoms/crates/client/src/networking/ws_wasm.rs -rw-r--r-- 3.1 KiB
9f2fc987 — ghostly_zsh shut up cargo.lock 8 months ago
                                                                                
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
use std::thread::yield_now;

use bevy_ecs::system::Resource;
//use crossbeam::channel::{unbounded, Receiver, Sender};
use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, SinkExt};
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
use wasm_bindgen_futures::spawn_local;
use web_sys::{MessageEvent, WebSocket};
use starkingdoms_common::packet::Packet;

const PORT: u16 = 3000;

#[derive(Debug)]
pub struct Socket(WebSocket);
unsafe impl Send for Socket {}
unsafe impl Sync for Socket {}

#[derive(Resource, Debug)]
pub struct Ws {
    socket: Socket,
    pub sender: UnboundedSender<Packet>,
    pub receiver: UnboundedReceiver<Packet>,
    packet_receiver: UnboundedReceiver<Packet>,
}

impl Ws {
    pub fn new() -> Self {
        let window = web_sys::window().unwrap();
        let ws = WebSocket::new(&format!("ws://{}:{}",
                window.location().hostname().unwrap(), PORT)).expect("Couldn't connect to server");
        let (packet_sender, receiver) = unbounded();
        //let packet_sender = Rc::new(RwLock::new(packet_sender));
        let (sender, packet_receiver) = unbounded();

        let ws_clone = ws.clone();
        let onopen_callback = Closure::<dyn FnMut()>::new(move || {
            let packet = Packet::ClientLogin {
                username: String::new(),
                save: None,
                jwt: None,
            };

            ws_clone.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to string")).expect("Failed to send packet");
        });
        ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
        onopen_callback.forget();
        let onmessage_callback = Closure::<dyn FnMut(_)>::new(move |e: MessageEvent| {
            //tracing::error!("{}", ws.ready_state());
            let data = e.data().as_string().expect("Expected string, found some other type");
            let data: Packet = serde_json::from_str(&data).expect("Received invalid json from server");
            let mut sender_clone = packet_sender.clone();
            spawn_local(async move {
                sender_clone.send(data).await.expect("Couldn't transmit packet to client");
            });
        });
        ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
        onmessage_callback.forget();
        Ws {
            socket: Socket(ws),
            sender,
            receiver,
            packet_receiver,
        }
    }
    pub fn send_all_packets_from_channel(&mut self) {
        //for packet in self.packet_receiver.iter() {
        while let Ok(Some(packet)) = self.packet_receiver.try_next() {
            self.socket.0.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server");
        }
    }
    pub fn send_packet(&mut self, packet: Packet) {
        let socket = self.socket.0.clone();
        spawn_local(async move {
            //while socket.ready_state() != 1 {  }
            socket.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server");
        });
    }
}