Giter Site home page Giter Site logo

embedded-websocket's Introduction

embedded-websocket

A lightweight rust websocket library for embedded systems no_std

This library facilitates the encoding and decoding of websocket messages and can be used for both clients and servers. The library is intended to be used in constrained memory environments like embedded microcontrollers which cannot reference the rust standard library. The library will work with arbitrarily small buffers regardless of websocket frame size as long as the websocket header can be read (2 - 14 bytes depending)

no_std support

You can use this library without linking the rust standard library. In your Cargo.toml file make sure you set the default features to false. For example:

embedded-websocket = { version = "x.x.x", default-features = false }

The optional (but recommended) framer module allows you to ergonomically work with full websocket frames without having to deal with the complexities of fragmented data. If you use it you will have to implement the Read and Write traits in that module because they are not available in no_std.

NOTE: If you get an error message like the following it means that you have not used default-features = false when declaring the dependency in your Cargo.toml file:

error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv7m-none-eabi` target may not be installed

Running the examples

The example below runs a websocket server that accepts client connections in a loop and returns back whatever text client sends. The client connects to the server, sends one "Hello, World!" message, waits for a response from the server then disconnects and terminates. Proper open and close handshakes are demonstrated.

To run the demo web server:

cargo run --example server

To run the demo websocket client:

cargo run --example client

or use this url in your browser http://127.0.0.1:1337/

Working example project

See https://github.com/ninjasource/led-display-websocket-demo for a complete end-to-end example of this library working with and stm32 m3 bluepill MCU and an embedded ethernet card.

Example websocket client usage:

The following example also found here initiates a opening handshake, checks the handshake response, sends a short message, initiates a close handshake, checks the close handshake response and quits.

// open a TCP stream to localhost port 1337
let address = "127.0.0.1:1337";
println!("Connecting to: {}", address);
let mut stream = TcpStream::connect(address).map_err(FramerError::Io)?;
println!("Connected.");

let mut read_buf = [0; 4000];
let mut read_cursor = 0;
let mut write_buf = [0; 4000];
let mut frame_buf = [0; 4000];
let mut websocket = WebSocketClient::new_client(rand::thread_rng());

// initiate a websocket opening handshake
let websocket_options = WebSocketOptions {
    path: "/chat",
    host: "localhost",
    origin: "http://localhost:1337",
    sub_protocols: None,
    additional_headers: None,
};

let mut framer = Framer::new(
    &mut read_buf,
    &mut read_cursor,
    &mut write_buf,
    &mut websocket,
);
framer.connect(&mut stream, &websocket_options)?;

let message = "Hello, World!";
framer.write(
    &mut stream,
    WebSocketSendMessageType::Text,
    true,
    message.as_bytes(),
)?;

while let Some(s) = framer.read_text(&mut stream, &mut frame_buf)? {
    println!("Received: {}", s);

    // close the websocket after receiving the first reply
    framer.close(&mut stream, WebSocketCloseStatusCode::NormalClosure, None)?;
    println!("Sent close handshake");
}

println!("Connection closed");

Example websocket server usage

The server example is a little too verbose to include in this readme, See server example

Async support

Async support is experimental and subject to significant API change.

License

Licensed under either MIT or Apache-2.0 at your option

embedded-websocket's People

Contributors

benbrittain avatar kskalski avatar ninjasource avatar stevefan1999-personal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

embedded-websocket's Issues

client example doesn't compile w/ latest rand

rand 0.7.3 works fine, but rand 0.8.3 does not.

37  |     let mut ws_client = ws::WebSocketClient::new_client(rand::thread_rng());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `rand_core::RngCore` is not implemented for `ThreadRng`

Support MQTT sub-protocol

I am currently writing a MQTT Client library for embedded, and would like to support delivery over Websocket.
From my understanding, Websocket should then consider MQTT as a sub-protocol.
In such use case, the connection would not go through HTTP at all.
All documentation in embedded-websocket I've seen assumes HTTP first, including the automatic protocol upgrade, which would not happen in my case, as connection would be in MQTT from the start. The Client should not even support HTTP.
Can you support such a use case?

std is required by sha1 because it does not declare #![no_std]

Having the following issue trying to compile the bare minimum:

Error:

   Compiling generic-array v0.14.6
   Compiling generic-array v0.12.4
   Compiling generic-array v0.13.3
   Compiling sha1 v0.6.1
error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv7em-none-eabi` target may not support the standard library
  = note: `std` is required by `sha1` because it does not declare `#![no_std]`
  = help: consider building the standard library from source with `cargo build -Zbuild-std

For more information about this error, try `rustc --explain E0463`.
error: could not compile `sha1` due to previous error
warning: build failed, waiting for other jobs to finish...

Even though I've set the dependency of embedded-websocket as instructed in the readme.
Also as far as I can see sha1 does declare #![no_std] but the error says no.

note: importing sha1 in my project (with default-features = false) and removing embedded-websocket does not produce the error.

What is going on here and what would be the proper way to resolve this issue?

rustc --version: rustc 1.66.0-nightly (758f19645 2022-10-24)
Cargo.toml:

[package]
name = "sandbox"
version = "0.1.0"
edition = "2021"

[dependencies]
embedded-websocket = { version = "0.8.0", default-features = false }

.cargo/config.toml:

[build]
target = "thumbv7em-none-eabi"

src/main.rs:

#![no_std]
fn main() {
    //println!("Hello, world!");
}

Kind regards,

Jack

Use a more push-based approach to handle async case.

Judging from the discussion on #13, it seems like adding async support would be a PITA because 1. maintenance hell with two copies of almost the same thing and 2. there is no standard regarding async and the use of io::Error in no_std situation which makes it very painful to write for in the first place.

I guess its time that we should discuss for a more modular, push-based approach similar to httparse. Then the user should handle the read write outside of the stream accordingly.

This of course means the responsibility would be offloaded to user and it will be a major semver break situation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.