cbsk_socket is a socket callback tool  
you can use cbsk_socket create TCP/WebSocket server or client, you don't need to focus on TCP/WebSocket read and write,
just focus on
business processing

### minimum supported Rust version

Rust 1.75.0

### now supported sockets

* tcp client √
* tcp server √
* ws client √
* ws server √

### tcp server example

Cargo.toml file:

```toml
fast_log = "1.6.12"
cbsk_base = { version = "0.1.7" }
cbsk_socket = { version = "0.3.12", features = ["tcp_server"] }
```

main.rs file:

```rust
use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use cbsk_base::{log, tokio};
use cbsk_socket::tcp::server::callback::TcpServerCallBack;
use cbsk_socket::tcp::server::client::TcpServerClient;
use cbsk_socket::tcp::server::config::TcpServerConfig;
use cbsk_socket::tcp::server::TcpServer;
use cbsk_socket::tcp::write_trait::WriteTrait;

#[tokio::main]
async fn main() {
    // print log to console
    let fast_config = fast_log::config::Config::default().console();
    fast_log::init(fast_config).unwrap();

    // start tcp server
    let addr = SocketAddr::new(IpAddr::from([0, 0, 0, 0]), 8080);
    let tcp_config = TcpServerConfig::new("test".into(), addr, false);
    let tcp_server = TcpServer::new(tcp_config.into(), TcpServerBusiness {}.into());
    let handle = tcp_server.start::<1024>();

    // wait handle
    handle.await.unwrap();

    // wait log flush
    log::logger().flush();
}

/// you tcp server business
pub struct TcpServerBusiness {}

/// business callback
impl TcpServerCallBack for TcpServerBusiness {
    async fn recv(&self, bytes: Vec<u8>, client: Arc<TcpServerClient>) -> Vec<u8> {
        println!("{} read bytes [{bytes:?}]", client.log_head);

        // send bytes to tcp client
        client.send_bytes(b"hello world").await;
        client.send_text("hello world").await;
        client.send_json(&"hello world".to_string()).await;

        Vec::new()
    }
}
```

### tcp client example

Cargo.toml file:

```toml
fast_log = "1.6.12"
cbsk_base = { version = "0.1.7" }
cbsk_socket = { version = "0.3.12", features = ["tcp_client"] }
```

main.rs file:

```rust
use std::net::{IpAddr, SocketAddr};
use std::time::Duration;
use cbsk_base::{log, tokio};
use cbsk_socket::config::re_conn::SocketReConn;
use cbsk_socket::tcp::client::callback::TcpClientCallBack;
use cbsk_socket::tcp::client::config::TcpClientConfig;
use cbsk_socket::tcp::client::TcpClient;
use cbsk_socket::tcp::write_trait::WriteTrait;

#[tokio::main]
async fn main() {
    // print log to console
    let fast_config = fast_log::config::Config::default().console();
    fast_log::init(fast_config).unwrap();

    // start tcp client
    let addr = SocketAddr::new(IpAddr::from([127, 0, 0, 1]), 8080);
    let tcp_config = TcpClientConfig::new("test".into(), addr, SocketReConn::enable(Duration::from_secs(3)));
    let tcp_client = TcpClient::new(tcp_config.into(), TcpClientBusiness {}.into());
    let read_handle = tcp_client.start::<1024>();

    // if tcp server connect success, send bytes to tcp server
    let write_handle = tokio::spawn(async move {
        loop {
            if tcp_client.is_connected() {
                tcp_client.send_bytes(b"hello world").await;
                tcp_client.send_text("hello world").await;
                tcp_client.send_json(&"hello world".to_string()).await;
            }

            tokio::time::sleep(Duration::from_secs(3)).await;
        }
    });

    // wait handle
    read_handle.await.unwrap();
    write_handle.await.unwrap();

    // wait log flush
    log::logger().flush();
}

/// you tcp client business
pub struct TcpClientBusiness {}

/// business callback
impl TcpClientCallBack for TcpClientBusiness {
    async fn recv(&self, bytes: Vec<u8>) -> Vec<u8> {
        println!("read bytes [{bytes:?}]");

        Vec::new()
    }
}
```

### other issues

websocket tls coming soon  
if y want to use tls, y can
use [tokio-tungstenite](https://crates.io/crates/tokio-tungstenite)([github](https://github.com/snapview/tokio-tungstenite))
