Lightweight, event-driven WebSockets for Rust.

Related tags

WebSocket ws-rs
Overview

WS-RS

Lightweight, event-driven WebSockets for Rust.

/// A WebSocket echo server
listen("127.0.0.1:3012", |out| {
    move |msg| {
        out.send(msg)
    }
})

Introduction

Build Status MIT licensed Crate

Homepage

API Documentation

This library provides an implementation of WebSockets, RFC6455 using MIO. It allows for handling multiple connections on a single thread, and even spawning new client connections on the same thread. This makes for very fast and resource efficient WebSockets. The API design abstracts away the menial parts of the WebSocket protocol and allows you to focus on application code without worrying about protocol conformance. However, it is also possible to get low-level access to individual WebSocket frames if you need to write extensions or want to optimize around the WebSocket protocol.

Getting Started

For detailed installation and usage instructions, check out the guide.

Features

WS-RS provides a complete implementation of the WebSocket specification. There is also support for ssl and permessage-deflate.

Testing

WS-RS is thoroughly tested and passes the Autobahn Test Suite for WebSockets, including the tests for permessage-deflate. Visit ws-rs.org to view the results of the latest test run.

Contributing

Please report bugs and make feature requests here.

Comments
  • Update to openssl 0.9 and fix #94

    Update to openssl 0.9 and fix #94

    This updates to OpenSSL 0.9.x and fixes the SNI issue.

    NB: breaking change! Due to OpenSSL security issues the build_ssl() method of the trait is now replaced by distinct build_ssl_client() and build_ssl_server() with different return types.

    opened by agalakhov 38
  • 0.5.4 should have been 0.6.0

    0.5.4 should have been 0.6.0

    ws reexports things from mio and mio was bumped with a breaking change, that should have been a breaking change in ws too. Why did you change back the version number from @SimonSapin's bump from 0.6.0 to 0.5.4?

    opened by nox 20
  • it takes a while to close the connection with a bad client

    it takes a while to close the connection with a bad client

    I have this broken client that get a ping timeout but the connection only drops after a couple of minutes. I guess that maybe Sender::close() asks the client to disconnect but my client doesn't.

    Also on_close is never called. In the documentation it seems that on_close is only called when we get something from the other endpoint while one of your comment seems to say that on_close is also called when the connection is lost.

    bug 
    opened by bbigras 20
  • Implementing Handler and Factory traits for a single struct

    Implementing Handler and Factory traits for a single struct

    (Question)

    I'm having a problem when implementing both traits for a since struct.

    When implementing the Factory, my associated type for Self::Handler is my 'client' struct. So I try to return self in that case, like so:

    impl Factory for MyClient {
        type Handler = MyClient;
        fn connection_made(&mut self, Sender) -> Self::Handler {
            *self
        }
    }
    

    However, this means I'm moving a borrowed struct, so this fails to compile:

       Compiling ws-pepe v0.1.0 (file:///Users/jalmeida/tmp/ws-pepe)
    src/main.rs:96:3: 96:8 error: cannot move out of borrowed content [E0507]
    src/main.rs:96          *self
                            ^~~~~
    src/main.rs:96:3: 96:8 help: run `rustc --explain E0507` to see a detailed explanation
    error: aborting due to previous error
    Could not compile `ws-pepe`.
    

    Could you possibly recommend a work around? I'm trying to have 3+ clients also act as servers in order to have a simple peer-to-peer conversation.

    I'm pretty sure I'm doing something wrong, but most of your examples all have separate structs for implementing handlers for clients and servers, so I can't see a trivial solution.

    question 
    opened by jonalmeida 14
  • Ability to return Result from io::Handler::handle_queue

    Ability to return Result from io::Handler::handle_queue

    In working on https://github.com/servo/servo/issues/14517, I discovered a need for the handle_queue function in io::Handler to be able to return a Result, so that servo can properly handle a connection failure. Currently, if there is e.g. an invalid domain passed to the websocket connect function, the handle_queue function can either swallow the error or panic, depending on the configuration of panic_on_new_connection. Unfortunately neither of these options are suitable for the use case in servo.

    enhancement 
    opened by shssoichiro 11
  • [permessage-deflate] Failed to perform decompression: -2

    [permessage-deflate] Failed to perform decompression: -2

    Encountered an error: WebSocket Protocol Error: Failed to perform decompression: -2
    Enable a logger to see more information.
    

    And I have no idea how to enable a logger! 😢


    I've set up a server with ssl and permessage-deflate. This is working excellently in "production": proxied through nginx and set up with a DNS record + SSL certificate.

    However, when developing locally, sending messages to the server cause it to fail decompression, and print the above error. (Note: even if I don't use the ssl feature, just using permessage-deflate causes the same issue)


    To reproduce

    1. Clone https://gitlab.com/fuzz-chat/server, commit 4147d152819a0f9de4c93b6b7e45b28f1033dad1
    2. cargo run
    3. In Chrome:
    var ws = new WebSocket('ws://localhost:9015?name=Mitch')
    

    then

    ws.send(JSON.stringify({
    	_type: "SEND_MESSAGE",
    	content: "4real though, this ws-rs library is awesome, and the docs are super legit!",
    	date: new Date()
    }))
    
    opened by mitchhentges 11
  • Dependencies in Cargo.toml

    Dependencies in Cargo.toml

    Hey,

    I noticed Cargo pulls lots of outdated dependencies into this project when building, to the point when it causes errors due to different versions of one crate (this one uses url v0.5.9, and hyper uses url v1.something) being used.

    Could you please update your Cargo.toml in order to use specified versions and not *s?

    Thanks in advance!

    EDIT: Just noticed you've got a stable-branch which contains actual non-starred versions. Then my request is to update the dependencies to their more recent versions.

    opened by NeoLegends 11
  • can't connect to wss endpoint with openssl 0.7.2

    can't connect to wss endpoint with openssl 0.7.2

    I am using 0.4.2. I noticed that openssl got upgraded to 0.7.2, not sure if that's the problem.

    Debug logs look like this:

    DEBUG:2015-12-16T23:56:08.530593:ws::handler: Handler is building request from wss://ws-feed.exchange.coinbase.com/.
    DEBUG:2015-12-16T23:56:08.530811:ws::handshake: Built request from URL:
    GET / HTTP/1.1
    Connection: Upgrade
    Host: ws-feed.exchange.coinbase.com:443
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: vWO5OTYQQRuk5o5Lq4NyMA==
    Upgrade: websocket
    
    
    ERROR:2015-12-16T23:56:08.530939:ws::io: Unable to establish connection to wss://ws-feed.exchange.coinbase.com/: WS Error <Ssl(StreamError(Error { repr: Os { code: 57, message: "Socket is not connected" } }))>
    
    bug compatibility 
    opened by alkis 11
  • ws::Sender.send_to

    ws::Sender.send_to

    Hello, I started a micro game with WS.

    I like to exchange 2 messages bewtween 2 connected users without broadcast. (Other users should not see this message)

    I find actualy an ugly way :

    1. broadcast message to avertise all than user_1 talk to user_2
    2. user_2 send a message to server to recover the message

    After traveling code, i suspected a lack :

    ws::Sender.send_to(user2_id)

    What do you think about it ?

    opened by mothsART 10
  • Some small changes

    Some small changes

    The main aim was to remove all unsafe code from the library (except for deflate/). So the responsibility is strictly shifted to the dependencies.

    I've separated the commits such that they can be cherry-picked easily as needed.

    I have not measured the performance impact; if one of the commits raises a concern I can try and do that later.

    opened by bluetech 10
  • Unable to connect from Client 2 if Client 1 is sending a lot of Messages to WS-RS Server

    Unable to connect from Client 2 if Client 1 is sending a lot of Messages to WS-RS Server

    Hi, I've been trying to send about 100,000 Messages each from two NodeJS clients and have noticed the following ... Steps to reproduce ...

    1. listen on socket in Server
    2. start client.js script that sends 100,000 Messages to Server
    3. start client2.js script in another tab that sends another 100,000 Messages to Server while client.js from step 2 is still running.

    What I've seen is that client2.js doesn't connect to Server until client.js has finished sending all it's Messages.

    Not sure what I am doing wrong here ... I would have expected client2.js to also connect to the Server and for the Server to receive msgs from both Clients at about similar times.

    Please also note that all components are running on the same machine.

    Thnx.

    bug 
    opened by neildsouza 10
  • how to set header,thanks

    how to set header,thanks

    if let Err(error) = connect("ws://echo.websocket.org", |out| {
        // Queue a message to be sent when the WebSocket is open
        if out.send("Hello WebSocket").is_err() {
            println!("Websocket couldn't queue an initial message.")
        } else {
            println!("Client sent message 'Hello WebSocket'. ")
        }
    
        // The handler needs to take ownership of out, so we use move
        move |msg| {
            // Handle messages received on this connection
            println!("Client got message '{}'. ", msg);
    
            // Close the connection
            out.close(CloseCode::Normal)
        }
    }) {
        // Inform the user of failure
        println!("Failed to create WebSocket due to: {:?}", error);
    }
    
    opened by bhltyou 0
  • Messages sent just before shutdown never go out

    Messages sent just before shutdown never go out

    I adapted the example in external_shutdown to echo messages.

    • The message sent by server to client 1 second before shutdown arrives
    • The message sent by server to client right before shutdown does not arrive

    Example:

    extern crate ws;
    
    use std::sync::mpsc::channel;
    use std::thread;
    use std::time::Duration;
    
    fn main() {
        let (tx, rx) = channel();
    
        let socket = ws::Builder::new()
            .build(move |out: ws::Sender| {
                // When we get a connection, send a handle to the parent thread
                tx.send(out).unwrap();
    
                // Dummy message handler
                move |_| {
                    println!("Message handler called.");
                    Ok(())
                }
            })
            .unwrap();
    
        let handle = socket.broadcaster();
    
        let t = thread::spawn(move || {
            socket.listen("127.0.0.1:3012").unwrap();
        });
    
        let c = thread::spawn(move || ws::connect("ws://127.0.0.1:3012", |out| {
            move |msg| {
                println!("Client got message: '{}'.", msg);
                Ok(())
            }
        }).unwrap());
    
        let to_client = rx.recv().unwrap();
        to_client.send("welcome").unwrap();
    
        // Wait for 5 seconds only for incoming connections;
        thread::sleep(Duration::from_millis(1000));
    
        to_client.send("going down").unwrap();
    
        // shutdown the server from the outside
        handle.shutdown().unwrap();
        println!("Shutting down server because no connections were established.");
    
        // Let the server finish up (whether it's waiting for new connections or going down)
        t.join().unwrap();
        c.join().unwrap();
    }
    

    How to get all the messages to go out before the server shuts down?

    I looked a bit at the code, but both send and shutdown seem to work through Command, so it's not quickly apparent to me what is wrong.

    opened by mverleg 0
  • DeflateHandler no longer works with newer versions of rustc

    DeflateHandler no longer works with newer versions of rustc

    See https://github.com/rust-lang/rust/issues/77499 for an example of a similar issue.

    In ws this is the error message when you try to use DeflateHandler:

    attempted to zero-initialize type `deflate::ffi::z_stream`, which is invalid
    

    Installing an older version with rustup makes it work: rustup install nightly-2020-09-26.

    As I understand, the issue is here:

    https://github.com/housleyjk/ws-rs/blob/6a47eaf9bda614ae8c987e0d9a09bf72040fa56b/src/deflate/context.rs#L70

    opened by AlexDaniel 0
  • Don't panic when trying to close a connection in

    Don't panic when trying to close a connection in "Connecting" state

    It's almost impossible to control the state of a WebSocket if there's a panic here (e.g. being able to start/stop a ws client or server).

    We must control each connection state to decide how to close a connection to avoid this panic, and most important point, to shutdown the WebSocket.
    ws::Sender::shutdown should never panic, because it's the only way to stop a running WebSocket, and we should not have to care about the state of connections.

    It's not happening in release mode, but using this crate in tests seems to be a valid use-case.

    Why not using an error log instead?

    opened by zazabe 0
Owner
Jason Housley
Jason Housley
Rust + wasm + websockets

This is a template repo for eframe, a framework for writing apps using egui.

Emil Ernerfeldt 12 Oct 3, 2022
Composable WebSockets made easy, for Rust 🦀

ezsockets Have you ever struggle with creating a WebSocket server or a client in Rust? This crate is for you. High level abstraction of WebSocket, han

Grzegorz Baranski 55 Dec 30, 2022
Rust API connector for Bybit's WebSockets APIs.

rust-bybit English | 简体中文 Unofficial Rust API connector for Bybit's WebSockets APIs. Disclaimer This is an unofficial Rust API connector for Bybit's A

yufuquant 12 Nov 12, 2022
A MITM Proxy Written in Rust 🦀! Toolkit for HTTP/1, HTTP/2, and WebSockets with SSL/TLS Capabilities. Learning Project.

Man In The Middle Proxy Description Rust-based Man in the Middle proxy, an early-stage project aimed at providing visibility into network traffic. Cur

null 158 Mar 9, 2023
Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions

websocat Netcat, curl and socat for WebSockets. Examples Connect to public echo server $ websocat ws://echo.websocket.org 123 123 ABC ABC Serve and c

Vitaly Shukela 5k Jan 4, 2023
Clearly a repo about websockets and their comparison...

Tags Go vs Typescript: Video 1 of the series is tag go-vs-ts-video-1 Current Project Video 2 and 3 are going to be likely Go vs Rust vs Typescript, bu

ThePrimeagen 344 Dec 31, 2022
😎 A custom invoke system for Tauri that leverages WebSockets

?? tauri-awesome-rpc This is a crate provides a custom invoke system for Tauri using a localhost JSON RPC WebSocket. Each message is delivered through

Victor Aremu 20 Dec 2, 2022
A command-line tool for exposing a wrapped program's standard IO using WebSockets/SSE

cmdpiped cmdpiped is a command-line tool for exposing a wrapped cli program's standard IO to WebSockets/SSE Installation Ready to use Binaries are ava

Geoffrey Mureithi 10 Nov 11, 2022
notiflux - subscribe over WebSockets, publish over REST

notiflux notiflux is a pub/sub server where clients subscribe over a WebSocket and messages are broadcast over a POST request How does it work? Client

Axel Örn Sigurðsson 3 Apr 9, 2024
Lightweight stream-based WebSocket implementation for Rust.

Tungstenite Lightweight stream-based WebSocket implementation for Rust. use std::net::TcpListener; use std::thread::spawn; use tungstenite::server::ac

Snapview GmbH 1.3k Jan 2, 2023
Jamsocket is a lightweight framework for building WebSocket-based application backends.

Jamsocket is a lightweight framework for building services that are accessed through WebSocket connections.

null 94 Dec 30, 2022
A lightweight framework for building WebSocket-based application backends.

Jamsocket Jamsocket is a lightweight framework for building services that are accessed through WebSocket connections. Services can either be native Ru

drifting in space 94 Dec 30, 2022
Lightweight websocket implement for stream transmission.

Lightws Lightweight websocket implement for stream transmission. Features Avoid heap allocation. Avoid buffering frame payload. Use vectored-io if ava

zephyr 25 Dec 27, 2022
SockJS server for rust language

SockJS server SockJS server for Actix framework. API Documentation Cargo package: sockjs SockJS is built with Actix web Minimum supported Rust version

Actix 63 Oct 7, 2022
A WebSocket (RFC6455) library written in Rust

Rust-WebSocket Note: Maintainership of this project is slugglish. You may want to use tungstenite or tokio-tungstenite instead. Rust-WebSocket is a We

Rust Websockets 1.3k Jan 6, 2023
A very-very simple url shortener for Rust

urlshortener-rs A very simple urlshortener for Rust. This library aims to implement as much URL shortener services as possible and to provide an inter

Victor Polevoy 39 Nov 20, 2022
A WebSocket (RFC6455) library written in Rust

Rust-WebSocket Rust-WebSocket is a WebSocket (RFC6455) library written in Rust. Rust-WebSocket provides a framework for dealing with WebSocket connect

Jason N 19 Aug 22, 2022
An aria2 websocket jsonrpc in Rust.

aria2-ws An aria2 websocket jsonrpc in Rust. Built with tokio. Docs.rs aria2 RPC docs Features Almost all methods and structed responses Auto reconnec

null 8 Sep 7, 2022
A simple toy websocket client to connect to Bitstamp.net and print the live order book written in Rust.

A simple toy websocket client to connect to Bitstamp.net and print the live order book written in Rust.

Nate Houk 1 Feb 14, 2022