2022-06-25 14:22:33 +00:00
|
|
|
#![allow(clippy::unused_io_amount)]
|
|
|
|
|
2022-06-26 10:59:48 +00:00
|
|
|
use futures_util::{
|
|
|
|
stream::{SplitSink, SplitStream},
|
|
|
|
SinkExt, StreamExt,
|
|
|
|
};
|
2022-06-25 14:22:33 +00:00
|
|
|
use tokio::{
|
|
|
|
io::{AsyncReadExt, AsyncWriteExt},
|
2022-06-26 10:59:48 +00:00
|
|
|
net::{
|
|
|
|
tcp::{OwnedReadHalf, OwnedWriteHalf},
|
|
|
|
TcpStream,
|
|
|
|
},
|
2022-06-25 14:22:33 +00:00
|
|
|
};
|
2022-06-26 10:59:48 +00:00
|
|
|
use tokio_tungstenite::WebSocketStream;
|
2022-07-29 19:55:21 +00:00
|
|
|
use tracing::info;
|
2022-06-25 14:22:33 +00:00
|
|
|
use tungstenite::Message;
|
|
|
|
|
|
|
|
use super::MAX_PACKET_LEN;
|
|
|
|
|
|
|
|
/// Handle WebSocket connection
|
|
|
|
pub async fn handle_websocket(stream: TcpStream, tcp_port: String) -> anyhow::Result<()> {
|
2022-06-26 10:35:58 +00:00
|
|
|
info!("New WebSocket Client: {}", stream.peer_addr()?);
|
|
|
|
|
2022-06-25 19:38:08 +00:00
|
|
|
// accept connection as WebSocket
|
2022-06-25 14:22:33 +00:00
|
|
|
let ws_stream = tokio_tungstenite::accept_async(stream).await?;
|
2022-06-25 19:38:08 +00:00
|
|
|
|
|
|
|
// connect to Tcp server
|
2022-06-25 14:22:33 +00:00
|
|
|
let tcp_stream = TcpStream::connect(format!("0.0.0.0:{}", tcp_port)).await?;
|
|
|
|
|
2022-06-25 19:38:08 +00:00
|
|
|
// split streams
|
2022-06-26 10:59:48 +00:00
|
|
|
let (tcp_read, tcp_write) = tcp_stream.into_split();
|
|
|
|
let (ws_write, ws_read) = ws_stream.split();
|
2022-06-25 14:22:33 +00:00
|
|
|
|
2022-06-25 19:38:08 +00:00
|
|
|
// tcp read -> ws write
|
2022-06-26 10:59:48 +00:00
|
|
|
tokio::spawn(tcp_to_ws(tcp_read, ws_write));
|
2022-06-25 14:22:33 +00:00
|
|
|
|
2022-06-25 19:38:08 +00:00
|
|
|
// ws read -> tcp write
|
2022-06-26 10:59:48 +00:00
|
|
|
ws_to_tcp(tcp_write, ws_read).await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Tcp read -> WebSocket write
|
|
|
|
async fn tcp_to_ws(
|
|
|
|
mut tcp_read: OwnedReadHalf,
|
|
|
|
mut ws_write: SplitSink<WebSocketStream<TcpStream>, Message>,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
// allocate an empty buffer
|
|
|
|
let mut buf = [0; MAX_PACKET_LEN];
|
|
|
|
|
|
|
|
loop {
|
|
|
|
// read buffer from tcp
|
|
|
|
let len = tcp_read.read(&mut buf).await?;
|
|
|
|
|
|
|
|
if len > 0 {
|
|
|
|
// select only used bytes from the buffer
|
|
|
|
let recv_buf = &buf[0..len];
|
|
|
|
// covert &[u8] buffer to a vector
|
|
|
|
let recv_vec = recv_buf.to_vec();
|
|
|
|
// create a `Message` type from buffer Vec<u8>
|
|
|
|
let msg = Message::Binary(recv_vec);
|
|
|
|
|
|
|
|
// write buffer to websocket
|
|
|
|
ws_write.send(msg).await?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// WebSocket read -> Tcp write
|
|
|
|
async fn ws_to_tcp(
|
|
|
|
mut tcp_write: OwnedWriteHalf,
|
|
|
|
mut ws_read: SplitStream<WebSocketStream<TcpStream>>,
|
|
|
|
) -> anyhow::Result<()> {
|
2022-06-25 14:22:33 +00:00
|
|
|
while let Some(msg) = ws_read.next().await {
|
2022-06-25 19:38:08 +00:00
|
|
|
// handle error in the message
|
2022-06-25 14:22:33 +00:00
|
|
|
let msg = msg?;
|
2022-06-25 19:38:08 +00:00
|
|
|
// create a buffer from a message
|
|
|
|
let buf = msg.into_data();
|
|
|
|
|
|
|
|
// write buffer to tcp
|
|
|
|
tcp_write.write(&buf).await?;
|
2022-06-25 14:22:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|