web: plumb websocket messages through to UI
This commit is contained in:
parent
f2042f284e
commit
30f3f14040
@ -2,6 +2,8 @@
|
|||||||
// - it's useful when you want to check your code with `cargo make verify`
|
// - it's useful when you want to check your code with `cargo make verify`
|
||||||
// but some rules are too "annoying" or are not applicable for your case.)
|
// but some rules are too "annoying" or are not applicable for your case.)
|
||||||
#![allow(clippy::wildcard_imports)]
|
#![allow(clippy::wildcard_imports)]
|
||||||
|
// Until https://github.com/rust-lang/rust/issues/138762 is addressed in dependencies
|
||||||
|
#![allow(wasm_c_abi)]
|
||||||
|
|
||||||
use log::Level;
|
use log::Level;
|
||||||
use seed::App;
|
use seed::App;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use graphql_client::GraphQLQuery;
|
use graphql_client::GraphQLQuery;
|
||||||
|
use letterbox_shared::WebsocketMessage;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use seed::{prelude::*, *};
|
use seed::{prelude::*, *};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -61,7 +62,7 @@ pub fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
|||||||
},
|
},
|
||||||
catchup: None,
|
catchup: None,
|
||||||
last_url: Url::current(),
|
last_url: Url::current(),
|
||||||
websocket: websocket::init(url, &mut orders.proxy(Msg::WebSocket)),
|
websocket: websocket::init(&mut orders.proxy(Msg::WebSocket)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,7 +664,15 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Msg::WebSocket(ws) => {
|
Msg::WebSocket(ws) => {
|
||||||
websocket::update(ws, &mut model.websocket, &mut orders.proxy(Msg::WebSocket))
|
websocket::update(ws, &mut model.websocket, &mut orders.proxy(Msg::WebSocket));
|
||||||
|
while let Some(msg) = model.websocket.updates.pop_front() {
|
||||||
|
orders.send_msg(Msg::WebsocketMessage(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Msg::WebsocketMessage(msg) => {
|
||||||
|
match msg {
|
||||||
|
WebsocketMessage::RefreshMessages => orders.send_msg(Msg::Refresh),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -831,4 +840,5 @@ pub enum Msg {
|
|||||||
CatchupExit,
|
CatchupExit,
|
||||||
|
|
||||||
WebSocket(websocket::Msg),
|
WebSocket(websocket::Msg),
|
||||||
|
WebsocketMessage(WebsocketMessage),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use std::rc::Rc;
|
use std::{collections::VecDeque, rc::Rc};
|
||||||
|
|
||||||
use letterbox_shared::WebsocketMessage;
|
use letterbox_shared::WebsocketMessage;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use seed::{prelude::*, *};
|
use seed::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wasm_sockets::{self, ConnectionStatus, EventClient, Message, WebSocketError};
|
use wasm_sockets::{self, ConnectionStatus, EventClient, Message, WebSocketError};
|
||||||
use web_sys::CloseEvent;
|
use web_sys::CloseEvent;
|
||||||
@ -31,16 +31,18 @@ const WS_URL: &str = "wss://6758.z.xinu.tv/api/ws";
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
web_socket: EventClient,
|
web_socket: EventClient,
|
||||||
web_socket_reconnector: Option<StreamHandle>,
|
web_socket_reconnector: Option<StreamHandle>,
|
||||||
|
pub updates: VecDeque<WebsocketMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------ ------
|
// ------ ------
|
||||||
// Init
|
// Init
|
||||||
// ------ ------
|
// ------ ------
|
||||||
|
|
||||||
pub fn init(_: Url, orders: &mut impl Orders<Msg>) -> Model {
|
pub fn init(orders: &mut impl Orders<Msg>) -> Model {
|
||||||
Model {
|
Model {
|
||||||
web_socket: create_websocket(orders).unwrap(),
|
web_socket: create_websocket(orders).unwrap(),
|
||||||
web_socket_reconnector: None,
|
web_socket_reconnector: None,
|
||||||
|
updates: VecDeque::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,39 +52,35 @@ pub fn init(_: Url, orders: &mut impl Orders<Msg>) -> Model {
|
|||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
WebSocketOpened,
|
WebSocketOpened,
|
||||||
TextMessageReceived(String),
|
TextMessageReceived(WebsocketMessage),
|
||||||
BinaryMessageReceived(ServerMessage),
|
|
||||||
CloseWebSocket,
|
|
||||||
WebSocketClosed(CloseEvent),
|
WebSocketClosed(CloseEvent),
|
||||||
WebSocketFailed,
|
WebSocketFailed,
|
||||||
ReconnectWebSocket(usize),
|
ReconnectWebSocket(usize),
|
||||||
|
#[allow(dead_code)]
|
||||||
SendMessage(ClientMessage),
|
SendMessage(ClientMessage),
|
||||||
SendBinaryMessage(ClientMessage),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(msg: Msg, mut model: &mut Model, orders: &mut impl Orders<Msg>) {
|
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||||
match msg {
|
match msg {
|
||||||
Msg::WebSocketOpened => {
|
Msg::WebSocketOpened => {
|
||||||
model.web_socket_reconnector = None;
|
model.web_socket_reconnector = None;
|
||||||
info!("WebSocket connection is open now");
|
info!("WebSocket connection is open now");
|
||||||
}
|
}
|
||||||
Msg::TextMessageReceived(msg) => {
|
Msg::TextMessageReceived(msg) => {
|
||||||
info!("recieved text {}", msg);
|
model.updates.push_back(msg);
|
||||||
}
|
|
||||||
Msg::BinaryMessageReceived(message) => {
|
|
||||||
error!("Client received binary message");
|
|
||||||
}
|
|
||||||
Msg::CloseWebSocket => {
|
|
||||||
model.web_socket_reconnector = None;
|
|
||||||
model.web_socket.close().unwrap();
|
|
||||||
}
|
}
|
||||||
Msg::WebSocketClosed(close_event) => {
|
Msg::WebSocketClosed(close_event) => {
|
||||||
info!("==================");
|
info!(
|
||||||
info!("WebSocket connection was closed:");
|
r#"==================
|
||||||
info!("Clean: {}", close_event.was_clean());
|
WebSocket connection was closed:
|
||||||
info!("Code: {}", close_event.code());
|
Clean: {0}
|
||||||
info!("Reason: {}", close_event.reason());
|
Code: {1}
|
||||||
info!("==================");
|
Reason: {2}
|
||||||
|
=================="#,
|
||||||
|
close_event.was_clean(),
|
||||||
|
close_event.code(),
|
||||||
|
close_event.reason()
|
||||||
|
);
|
||||||
|
|
||||||
// Chrome doesn't invoke `on_error` when the connection is lost.
|
// Chrome doesn't invoke `on_error` when the connection is lost.
|
||||||
if !close_event.was_clean() && model.web_socket_reconnector.is_none() {
|
if !close_event.was_clean() && model.web_socket_reconnector.is_none() {
|
||||||
@ -107,9 +105,6 @@ pub fn update(msg: Msg, mut model: &mut Model, orders: &mut impl Orders<Msg>) {
|
|||||||
let txt = serde_json::to_string(&msg).unwrap();
|
let txt = serde_json::to_string(&msg).unwrap();
|
||||||
model.web_socket.send_string(&txt).unwrap();
|
model.web_socket.send_string(&txt).unwrap();
|
||||||
}
|
}
|
||||||
Msg::SendBinaryMessage(_msg) => {
|
|
||||||
error!("Attempt to send binary message, unsupported");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +155,7 @@ fn decode_message(message: Message, msg_sender: Rc<dyn Fn(Option<Msg>)>) {
|
|||||||
let msg: WebsocketMessage = serde_json::from_str(&txt).unwrap_or_else(|e| {
|
let msg: WebsocketMessage = serde_json::from_str(&txt).unwrap_or_else(|e| {
|
||||||
panic!("failed to parse json into WebsocketMessage: {e}\n'{txt}'")
|
panic!("failed to parse json into WebsocketMessage: {e}\n'{txt}'")
|
||||||
});
|
});
|
||||||
msg_sender(Some(Msg::TextMessageReceived(txt)));
|
msg_sender(Some(Msg::TextMessageReceived(msg)));
|
||||||
}
|
}
|
||||||
m => error!("unexpected message type received of {m:?}"),
|
m => error!("unexpected message type received of {m:?}"),
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user