// This file is part of Substrate.
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
use async_std::net::{TcpListener, TcpStream};
use core::pin::Pin;
use futures::prelude::*;
use soketto::handshake::{server::Response, Server};
use std::{io, net::SocketAddr};
/// Configuration for a [`WsServer`].
pub struct Config {
/// IP address to try to bind to.
pub bind_address: SocketAddr,
/// Maximum size, in bytes, of a frame sent by the remote.
///
/// Since the messages are entirely buffered before being returned, a maximum value is
/// necessary in order to prevent malicious clients from sending huge frames that would
/// occupy a lot of memory.
pub max_frame_size: usize,
/// Number of pending messages to buffer up for sending before the socket is considered
/// unresponsive.
pub send_buffer_len: usize,
/// Pre-allocated capacity for the list of connections.
pub capacity: usize,
}
/// Identifier for a connection with regard to a [`WsServer`].
///
/// After a connection has been closed, its [`ConnectionId`] might be reused.
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct ConnectionId(u64);
/// A WebSocket message.
pub enum Message {
Text(String),
Binary(Vec),
}
/// WebSockets listening socket and list of open connections.
pub struct WsServer {
/// Value passed through [`Config::max_frame_size`].
max_frame_size: usize,
/// Endpoint for incoming TCP sockets.
listener: TcpListener,
/// Pending incoming connection to accept. Accepted by calling [`WsServer::accept`].
pending_incoming: Option,
/// List of TCP connections that are currently negotiating the WebSocket handshake.
///
/// The output can be an error if the handshake fails.
negotiating: stream::FuturesUnordered<
Pin<
Box<
dyn Future