YAC (Yac is Another Chat) is an example of Chat using WebSocket.

Overview

YAC Rust

YAC (Yac is Another Chat) is an example of Chat using WebSocket. Because often the example you find in internet are "not so production ready", I would like to try to implement something more robust.

See slides for the introduction.

ToC

Main struture

The main parts in this project are:

  • ChatService
  • WsPool
  • Handler

Also other parts are still important like CredentialService but it is not so WebSocket related.

ChatService

This service keeps track which users are in which chats. It stores also the chats.

WsPool

This pool contains all websockets currently connected to the server

Handler

HTTP handlers allows to expose business functionality through a JSON REST interface.

Component interation

Channel approach

To WsPool

Near by WsPool struct, there's a process_ws_pool function that iterate over all WebSocket events. In this way, we don't have a lot of futures polling: just one. process_ws_pool, also, is the only one piece of the code that can access to the WsPool instance. That is guarandee by Rust itself: WsPool cannot send among threads safetly and there's no Arc > . So At compile time, we have the guarandee that process_ws_pool has an exclusive access to WsPool. And that is amazing.

But a issue raised here: if WsPool stores all WebSockets and only process_ws_pool can access to it, how we can add to it new WebSockets?

The answer is: use channels. In fact process_ws_pool iterate over a channel typed Item that is a enum. One variant is used for adding WebSocket and another one for removing them.

In this way, the ws handler is able to add and remove WebSockets from WsPool.

But also ChatService needs to interact with WsPool: when ChatService decides to send messages, it needs to request to WsPool to send those messages. So, how is ChatService able to interact with WsPool?

The answer is always the same: use channels. In fact, the receiver side of a channel is not clonable, but the sender one is.

So, both the handler and the ChatService is able to interact with WsPool.

To/From Redis (Pub/Sub)

Because in production you may want to deploy multiple instances of you web service and because the WebSocket is stateful, you need to dispatch an event among the instances in order to inform them that a new message arrived. To do that, the project uses redis in Pub/Sub mode.

So, when a device sends a new message requests, WsPool intercept the request and publish it to a redis channel. All running instances capture that message (thanksful to the subscription) and invoke the ChatService in order to know which is the users are in that chat. For that users, ChatService fetch which DeviceId belong to the users and invoke asynchronously WsPool. WsPool iterates over the DeviceId list and sends the message to them.

But again, I would not like to link deeper WsPool and ChatService with redis: in the future, we cann choose to use a different approach/service. So, for interacting with redis (aka for sending messages to redis and for listening messages from redis), we used the channel capability: when WsPool needs to inform that a new message arrives, it that message into the channel and externally sends it to redis channel (see to_redis in lib.rs). From external process (see from_redis in lib.rs), we listen the messages from redis and invoke ChatService indirectly using a channel (see process_chat in chat_service.rs)

Production considerations

The code uses always asychronous code for simulating database interation even where not needed. For production, this could impact the performance so please consider to change it before go live.

Development

For running it locally:

cargo run

For running test:

cargo test

NB: you need always a running redis server on "redis://127.0.0.1/" (port 6379). You can change it, if you want.

You might also like...
Cross-platform, low level networking using the Rust programming language.

libpnet Linux ∪ OS X Build Status: Windows Build Status: Discussion and support: #libpnet on freenode / #rust-networking on irc.mozilla.org / #rust on

Simple VPN implemented using rust
Simple VPN implemented using rust

fubuki Simple VPN implemented using rust fubuki是类似与tincVPN的简单组网工具 不支持对等NAT 支持的平台: Windows Linux 工作机制 它由一台拥有公网IP的服务器来维持各个内网客户端的实际地址映射,在客户端和客户端之间实现P2P通信

Implementing Bendersnatch curve using Arkwork's framework in Rust.

This is a reference implementation of Bendersnatch curve using Arkwork's framework in Rust. The spec of the curve is available here. There was also a Python reference implementation here.

WIP / POC for using the BL602 wifi blob from Rust

BL602 Wifi Rust This is work in progress and currently more a proof of concept. The code is awfully hacked together - just enough to make it work. It

Examples of interacting with a Polkadot node using Rust

Examples of interacting with a Polkadot node Some examples of using JSON RPC to interact with a Polkadot node, working up to manually building and sub

Download a file using multiple threads in parallel for faster download speeds.

multidl Download a file using multiple threads in parallel for faster download speeds. Uses 0 external dependencies. Usage Usage: multidl [--help] ADD

Tunnel TCP traffic through SOCKS5 or HTTP using a TUN interface.

tun2proxy Tunnel TCP traffic through SOCKS5 or HTTP on Linux. Authentication not yet supported. Error handling incomplete and too restrictive. Build C

The Graph is a protocol for building decentralized applications (dApps) quickly on Ethereum and IPFS using GraphQL.

Graph Node The Graph is a protocol for building decentralized applications (dApps) quickly on Ethereum and IPFS using GraphQL. Graph Node is an open s

Modrinth API is a simple library for using Modrinth's API in Rust projects

Ferinth is a simple library for using the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

Owner
Tommaso Allevi
Tommaso Allevi
Small example using Slint on the MXCHIP IoT DevKit (AZ3166)

Small example using Slint on the MXCHIP IoT DevKit (AZ3166) To Build and run: You need: The hardware: an MXCHIP IoT DevKit https://en.mxchip.com/az316

Olivier Goffart 4 Dec 24, 2022
An example of a common Wi-Fi set up scenario on ESP32 using Rust

UTC IoT fetcher This repo is an example of how to configure a Wi-Fi client on an ESP32-based IoT device using an external device connection to the int

Max Wase 4 Jan 19, 2023
Yet Another File Transfer Protocol.

yaftp Yet Another File Transfer Protocol. Build & Run $> cargo build --release Features C2C Lightweight Per something per session High performence Res

b23r0 20 Sep 22, 2022
Rust library that helps you change the domain of the link to another domain 🦀🔐

Rust library that helps you to change the domain of the link to another domain, the library helps with privacy. It can be used to change the domain of sites that do not care about privacy to another that does.

TheAwiteb 2 Mar 28, 2022
Yet another youtube (and more) down loader

Yet another youtube (and more) down loader

Cthulhux 203 Dec 25, 2022
A telnet chat server written in Rust, running on Lunatic.

Lunatic.chat A telnet chat server written in Rust, running on Lunatic. If you just would like to try it out, join the hosted version with: # US server

Lunatic 101 Jan 2, 2023
A Markov chain based Discord chat bot.

A Markov chain based Discord chat bot. Building It is recommended to use cargo.

Dominik Miedziński 1 Dec 26, 2021
A set of Rust crates for interacting with the Matrix chat network.

Ruma – Your home in Matrix. A set of Rust crates (libraries) for interacting with the Matrix chat network. website • chat • documentation (unstable) G

Ruma 441 Dec 26, 2022
Super simple tokio chat server for educational purposes.

achat A collection of simple modules which showcase simple use of tasks, channels, and other tokio primitives to implement simple networking applicati

Rafael Bachmann 2 Dec 29, 2022
An asset for HardHat C2 written in Rust as an example/demo

Rivet An asset for HardHat C2 written in Rust as an example/demo Installation and Use Download cargo for the operating system the team server will be

HardHat Toolbox 5 Oct 24, 2023