Clearly a repo about websockets and their comparison...

Overview

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, but I want it to be more complex. I want a server that has to perform a ton of operations and have real deadlines.

  • Everything will be done live on Twitch.

Completed

  • We have successfully created the socket pair emitting server in Go, Rust, Typescript, and RxJS + Typescript.

In Flight

  • Working through the TypeScript implementation.

To Be Completed

  • Fill this in me from the future

Test Client

A test client should do the following.

  1. request an Id
  2. connect to the ws server
  3. wait for play command
  4. send fire commands every X amount of milliseconds
  5. Whether client wins or loses, the client should check their stats after each round.

The cycle should repeat starting from point 2 over and over again.

Server

Getting stats

A simple post request for stats with a stat id should return the stats of a given id retrieved from a database.

Server Stats

A post request for server stats should emit the following (these stats are based off the last server stat request)

  • active connections
  • active games
  • stat requests processed
  • stats stored
  • games played
  • shots taken
  • total ticks processed
  • count of ticks exceeding 17ms, 19ms, 21ms, 26ms, 36ms, 50ms, 100ms
    • this will include processing time + sleep time.
    • an Ideally working server will approximately 60 tick server
  • linode stats? Unsure, working with linode on what is available.
Playing the game

The server, when a new web socket connection is established will either start a wait period for the next connection or start a game. The two connections will remain open until one player is defeated. At that point the connection should be closed.

Game Loop

A game loop will be instantiated with two sockets. The game loop will send out a ready and play signal.

Every tick (approx 16 ms) the game loop will execute the following in the following order:

  1. report stats
  2. get a batch of updates to process (msgs from sockets)
  3. process said updates
  4. update every location of items
  5. check for collisions
  6. check for state of game
  7. determine elapsed time and sleep for enough ms to maintain 60fps

this loop will repeat until one player has 0 health

FAQ

What languages

Rust, Go, and Typescript.

  • 69% chance i'll stop trying to make Rust work. Its effing hard.

Idiomatic vs Similar behavior

This is a tough trade off. I want to be able to build the servers in such a way that each one is as "idiomatic" as possible but the following I will concede the attempt.

  1. In places where I don't even know what is idiomatic
  2. Where doing the idiomatic thing would actually be bad for performance
  3. Where doing the idiomatic thing would make the other servers very different in implementation. Thus hard to say its an "apples to apples" comparison.

RxJS?

I do want to make the TS server implemented with and without rxjs. It will likely be pretty hard to do this, but I believe I can :)

Metrics for success?

The primary metric for success will be connections * 1 / (count of bad ticks / total ticks). This should give a relatively interesting score.

Any Secondary Metrics

If I can get linode metrics out via some end point, then I'll also figure out a nice CPU and Memory metric over time.

Expectations?

I expect that Rust will be faster and more memory efficient, but I worry that I am unable to create something that is this. I will likely over clone and over heap use because I am terrible at the language. So this may hinder it.

Second I expect Go to be the easiest to implement, even though of the three languages I am the least experienced in go by a very significant amount.

Lastly, I think implementing typescript with two different methods (rxjs vs not rxjs) will be a pain in the ass and make me want to quit.

Comments
  • Alternate implementation for Rust

    Alternate implementation for Rust

    I saw your video on YouTube and was surprised that the bullet game code written in Rust was not performing as good as (if not better than) Go. This made me curious and I went through the Rust code.

    I've created an alternate implementation of the game in Rust which doesn't use any Mutex and very few channels. Hopefully this one should perform better than the current implementation.

    To compile and run:

    cd rust-alternate/
    cargo build --release --bin server
    ./target/release/server start
    

    If you want to change log level:

    RUST_LOG=error ./target/release/server start
    

    You can test this using the same game_player.rs in current code.

    opened by devashishdxt 34
  • go-server suggestions

    go-server suggestions

    Hi,

    I loved your NodeJS/TS vs Go video and I thought I would check out the code, and I wanted to make some suggestions... In the end it snowballed, and there seems to be a lot of changes but I assure you it is mostly just gofmt that has formatted the code.

    Here are the notable changes suggestions by order of importance:

    • Fixed a race in your HandleNewConnection Handler, where the OtherSocket variable could have been corrupted. I suspect the reason you never ran into this issue is that you ran on a single core and so only one goroutine could run at a time.
    • Made the channels return Messages and not pointers to Messages. By using pointers you force the Go runtime to allocate to the heap and put additional pressure on the GC... This might me an over optimisation and could actually end up being worse. But my gut is that in this situation its better to not be creating thousands of messages on the heap if you can avoid it.
    • Refactored the server function, and removed the needless Socket interface...

    Anyways, Loved your video, was hoping you would check out these suggested changes, and no worries if you don't want to merge. I did go a little overboard.

    Best of luck, and can't wait to see your next video.

    opened by davidmdm 5
  • node.js UV_THREADPOOL_SIZE

    node.js UV_THREADPOOL_SIZE

    First things first, I don't think the node.js can out perform golang.

    That being said when running a SYSCALL heavy code with a lot of delegation you should bump the thread pools size from 4 to 128 at least (using the env UV_THREADPOOL_SIZE).

    More docs here: http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling

    opened by mpodolsk 2
  • Elixir version

    Elixir version

    opened by ryanwinchester 2
  • queue locks are so 2020

    queue locks are so 2020

    removes the sync.mutex out of the message queue in favor of a lock less concurrent safe queue.

    go fmt on the master branch seems out of date or something as go fmt now forces tabs. Merge #12 first to see actual changes. Or hit that ignore whitespace diff button

    I think this in memory queue is faster than channels, but it doesn't block so it would require more refactoring likely with sleeps to handle an empty queue in order to replace all the channels with the queue implementation. This is very useful in real world environments where the queue is rarely starved. If the sleeps aren't tuned right and the queue was starved it would add latency over the channel implementation, however under significant load the queue would never starve and be faster than channels.

    opened by Ashtonian 0
  • VODs missing

    VODs missing

    I was hoping to learn server programming by watching the VODs from the start, building and running the commits: https://github.com/ThePrimeagen/tyrone-biggums/blob/1ddb63fac0a26c6c37ec39ceb7b6175b127fdcbc/README.md?plain=1#L37

    But it seems like you where streaming on youtube when you started the project, then set the past live streams to private.

    Could you set the past live streams to unlisted and provide the links please?

    opened by tom-huntington 0
  • Incremental refactor of RxJS implementation.

    Incremental refactor of RxJS implementation.

    While the overall diff might look like a complete rewrite, I stuck with your approach and simply made incremental changes, commit-by-commit. Overall this is still not how I'd implement a server (if RxJS and Node were requirements for some reason), it's just a refactor of what's here. See commits for details.

    High Level:

    1. There were several places where you were creating subscriptions but not unsubscribing them or cleaning them up.
    2. There was a LOT of unnecessary RxJS in this example. As an example, there were a couple of cases where a Subject was being used to create a unicast observable, or to wrap what was already multicast with an observable.
    3. There were other unnecessary abstractions I'd have steered clear of that might also be hurting your callbacks implementation.
    4. The tests never worked for me. Two were broken out of the gate. I deleted the rxjs-related tests that no longer align with the implementation. I didn't add new tests, however. If you want to test those, the function that create the Observables are exported from the modules they live in, and you can test those in isolation provided mocks of things like sockets, etc.
    5. I was unable to run any of your tests. In your videos it seems you're running some Netflix-specfic python script under ~/work when you spin up your docker image.

    As a whole, this example would make a great sample to use to showcase incremental refactoring of code that wasn't meeting requirements. In all, it didn't even take that long. Incremental refactor is a skill I can't recommend enough.

    There may be some argument that "I didn't do this the RxJS way". But there is no RxJS way. I can't control what weird tutorials or explainers are out in the wild. It's just a set of tools.

    All of that said:

    1. IMO, I would never implement a "high speed game server", especially one this simple, in Node. 🤷
    2. Callbacks (aka no/little abstraction) will always beat any additional abstraction. Especially if that abstraction isn't well leveraged.
    3. This is probably still slower than callbacks. I'm sure you'll editorialize that on YouTube or Twitter as "A disaster" or a "toilet fire" (your exact words), but do what you will.

    At this point the ball is in your court. I'm attempting to help you with your comparison, good luck with your YouTube channel.

    opened by benlesh 8
  • Not able to run benchmarks for the typescript project

    Not able to run benchmarks for the typescript project

    Hey !! Thanks for the amazing video https://www.youtube.com/watch?v=h7UEwBaGoVo I am trying to do some optimizations in the typescript project (in terms of web server choice, code organization, and more) But I am running into an issue while running the benchmarks for ts.

    I started the server using $> node typescript/dist/index.js callback localhost 9999 started client using $> cargo +nightly run --bin test_client 2 localhost --path / --port 9999

    Running the client is crashing the server with

    undefined:1
    !join foo0
    ^
    
    SyntaxError: Unexpected token ! in JSON at position 0
        at JSON.parse (<anonymous>)
        at WebSocket.<anonymous> (/Users/shreymehta/projects/tyrone-biggums/typescript/dist/server/socket.js:13:34)
        at WebSocket.emit (events.js:315:20)
        at Receiver.receiverOnMessage (/Users/shreymehta/projects/tyrone-biggums/typescript/node_modules/ws/lib/websocket.js:1098:20)
        at Receiver.emit (events.js:315:20)
        at Receiver.dataMessage (/Users/shreymehta/projects/tyrone-biggums/typescript/node_modules/ws/lib/receiver.js:528:14)
        at Receiver.getData (/Users/shreymehta/projects/tyrone-biggums/typescript/node_modules/ws/lib/receiver.js:446:17)
        at Receiver.startLoop (/Users/shreymehta/projects/tyrone-biggums/typescript/node_modules/ws/lib/receiver.js:148:22)
        at Receiver._write (/Users/shreymehta/projects/tyrone-biggums/typescript/node_modules/ws/lib/receiver.js:83:10)
        at writeOrBuffer (_stream_writable.js:352:12)
    

    I can see this project is being worked upon daily. Can you please point me to the commit at which this comparison was done?

    opened by smehta91 2
  • Consider trending Rust frameworks to increase productivity

    Consider trending Rust frameworks to increase productivity

    Consider the following frameworks to make server side development coconut oil smooth.

    • Axum https://github.com/tokio-rs/axum/blob/main/examples/websockets/src/main.rs
    • Poem https://github.com/poem-web/poem/blob/master/examples/poem/websocket-chat/src/main.rs
    opened by andrewwebber 0
Owner
ThePrimeagen
ThePrimeagen
Lightweight, event-driven WebSockets for Rust.

WS-RS Lightweight, event-driven WebSockets for Rust. /// A WebSocket echo server listen("127.0.0.1:3012", |out| { move |msg| { out.send(ms

Jason Housley 1.3k Jan 8, 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
Synchronized state machines for Rust over WebSockets.

Aper is a framework for real-time sharing of application state over WebSockets.

null 191 Dec 20, 2022
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
😎 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
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 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
A webserver and websocket pair to stop your viewers from spamming !np and "what's the song?" all the time.

spotify-np ?? spotify-np is a Rust-based local webserver inspired by l3lackShark's gosumemory application, but the catch is that it's for Spotify! ??

Noire 2 Aug 27, 2022
ChatApp made using the standard library net module and tui-rs.

chatui Simple chat application. You'll need both chatui_server and chatui_client to run this application. Installation With cargo cargo install chatui

Gauravsingh Sisodia 6 Dec 15, 2021
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
"Last Mile" streaming server and client

TSLM - Terminal Stream Last Mile This is an asynchronous WebSocket server written in Rust using tokio-tungstenite. It allows a WebSocket client to per

null 4 Nov 9, 2023
A command line tool for people of transgender experience to replace their deadname within a Git repo.

chowndn (Change Owner from Dead Name) A command line tool for people of transgender experience to replace their dead name within a Git repo. See chown

Christi Miller 23 Dec 6, 2022
Rust implementation of PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols

Rust PRECIS Framework libray PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols as descr

Santiago Carot-Nemesio 1 Oct 20, 2022
A comparison of operating systems written in Rust

Rust OS comparison A comparison of operating systems written in Rust. There are several open source operating systems written in Rust. Most of them ar

Markus Kohlhase 492 Jan 8, 2023
Simple comparison app for iRacing car setups.

CarTunes Simple comparison app for iRacing car setups. About Export a setup in the iRacing garage and CarTunes will let you compare it with other setu

Jay Oster 31 Jan 7, 2023
🧹 Quick & dirty fuzzy path comparison

?? fuzzypath Quick & dirty fuzzy path comparison Comparison rules ✅ Case insensitive ✅ Backslashes are normalized to forward slashes ✅ Trailing slashe

William 4 May 19, 2022
Generate markdown comparison tables from `cargo-criterion` JSON output

criterion-table Generate markdown comparison tables from Cargo Criterion benchmark JSON output. Currently, the tool is limited to Github Flavored Mark

Scott Meeuwsen 11 Dec 16, 2022
rust channel benchmarks to keep stat of performance of Kanal library in comparison with other competitors.

Rust Channel Benchmarks This is a highly modified fork of the crossbeam-channel benchmarks. to keep track of Kanal library stats in comparison with ot

Khashayar Fereidani 14 Dec 21, 2022