Commit graph

81 commits

Author SHA1 Message Date
Sergey Stepanov
3bd32715cb
Remove unused fonts 2023-04-23 19:55:39 +03:00
Sergey Stepanov
3c2c24038d
Hack 2023-03-29 13:03:31 +03:00
sergystepanov
3bd959b4ef
Refactored v3 (#350)
This PR contains refactored code.

**Changelog**
- Added new net code (the communication architecture was left intact).
- All network client IDs now have custom type `network.Uid` backed by github.com/rs/xid lib.
  ```
  The string representation of a UUID takes 32 bytes, and the new type will take just 16.
  Because of Golang JSON serialization problems with omitting zero-length empty slices (it can't) 
  and the need to use UID values as map keys (maps don't support slices as keys), 
  IDs are stored as strings (for now).
  ```
- A whole new WebSocket client/server implementation was added, as well as a new communication layer with synchronous and async call handlers.
  - WebSocket connections now support dedicated Ping/Pong frames as opposed to original ping text messages.
  - Used Gorilla WebSocket library doesn't allow concurrent (simultaneous) reads and writes, so this part was handled via send channel synchronization.
- New API structures can be found in the `pkg/api` folder.
- New communication protocol can be found in the `pkg/com/*` folder.
- Updated communication protocol is based on JSON-encoded messaging through WebSocket and has the following structure:
  ```
  Packet
    [id] string — a globally unique identification tag for the packet to track it trough a chain of requests.
    t uint8 — contains packet type information (i.e. INIT_PACKET, SDP_OFFER_PACKET, ...).
    [p] any — contains packet data (any type).

  Each packet is a text message in JSON-serialized form (WebSocket control frames obviously not).
  ```
  ```
  The main principle of this protocol and the duplex data exchange is:
  the one who initializes connection is called a client, and 
  the one who is being connected to is called a server. 
  With the current architecture, the coordinator is the server, the user browsers and workers are the clients.

            ____           ____
           ↓    ↑         ↑    ↓
     browser ⟶ coordinator ⟵ worker
       (c)          (s)         (c)

  One of the most crucial performance vise parts of these interactions is that 
  all the server-initiated calls to clients should be asynchronous!
  ```
  - In order to track synchronous calls (packets) with an asynchronous protocol, such as WebSocket, each packet may have an `id` that should be copied in all subsequent requests/responses.
  - The old `sessionID` param was replaced by `id` that should be stored inside the `p` (payload) part of the packet.
- It is possible to skip the default ping check for all connected workers on every user connection and just pick the first available with the new roundRobin param in the coordinator config file `coordinator.roundRobin: true/false`.
- Added a dedicated package for the system API (pkg/api/*).
- Added structured logging system (zerolog) for better logging and cloud services integration.
- Added a visual representation of the network message exchange in logs:
  ```
  ...
  01:00:01.1078 3f98 INF w → c Handshake ws://localhost:8000/wso
  01:00:01.1138  994 INF c ← w Handshake localhost:8000
  01:00:01.1148  994 INF c ← w Connect cid=cep.hrg
  01:00:01.1158  994 DBG c     connection id has been changed to cepl7obdrc3jv66kp2ug cid=cep.hrg
  01:00:01.1158 3f98 INF w → c Connect cid=cep.2ug
  01:00:01.1158  994 INF c     New worker / addr: localhost, ...
  01:00:01.1158 3f98 INF w     Connected to the coordinator localhost:8000 cid=cep.2ug
  01:00:02.5834  994 INF c ← u Handshake localhost:8000
  01:00:02.6175  994 INF c ← u Connect cid=cep.hs0
  01:00:02.6209  994 INF c     Search available workers cid=cep.hs0
  01:00:02.6214  994 INF c     Found next free worker cid=cep.hs0
  01:00:02.6220  994 INF c → u InitSession cid=cep.hs0
  01:00:02.6527  994 INF c ← u WebrtcInit cid=cep.hs0
  01:00:02.6527  994 INF c → w ᵇWebrtcInit cid=cep.hrg
  01:00:02.6537 3f98 INF w ← c WebrtcInit cid=cep.2ug
  01:00:02.6537 3f98 INF w     WebRTC start cid=cep.2ug
  ...
  ```
- Replaced a monstrous Prometheus metrics lib.
- Removed spflag dependency.
- Added new `version` config file param/constant for compatibility reasons.
- Bump the minimum required version for Go to 1.18 due to use of generics.
- Opus encoder now is cached and the default config is 96Kbps, complexity 5 (was 196Kbps, 8).
- Changed the default x264 quality parameters to `crf 23 / superfast / baseline` instead of `crf 17 / veryfast / main`.
- Added a separate WebRTC logging config param `webrtc.logLevel`.
- Worker now allocates much less memory.
- Optimized and fixed RGB to YUV converter.
- `--v=5` logging cmd flag was removed and replaced with the `debug` config parameter.


**Breaking changes (migration to v3)**
- Coordinator server API changes, see web/js/api/api.js.
- Coordinator client event API changes:
  - c `GAME_PLAYER_IDX_CHANGE` (string) -> `GAME_PLAYER_IDX` (number)
  - c `GAME_PLAYER_IDX` -> `GAME_PLAYER_IDX_SET`
  - c `MEDIA_STREAM_INITIALIZED` -> `WEBRTC_NEW_CONNECTION`
  - c `MEDIA_STREAM_SDP_AVAILABLE` -> `WEBRTC_SDP_OFFER`
  - c `MEDIA_STREAM_CANDIDATE_ADD` -> `WEBRTC_ICE_CANDIDATE_RECEIVED`
  - c `MEDIA_STREAM_CANDIDATE_FLUSH` -> `WEBRTC_ICE_CANDIDATES_FLUSH`
  - x `MEDIA_STREAM_READY` -> **removed**
  - c `CONNECTION_READY` -> `WEBRTC_CONNECTION_READY`
  - c `CONNECTION_CLOSED` -> `WEBRTC_CONNECTION_CLOSED`
  - c `GET_SERVER_LIST` -> `WORKER_LIST_FETCHED`
  - x `KEY_STATE_UPDATED` -> **removed**
  - n `WEBRTC_ICE_CANDIDATE_FOUND`
  - n `WEBRTC_SDP_ANSWER`
  - n `MESSAGE`
- `rtcp` module renamed to `webrtc`.
- Controller state equals Libretro controller state (changed order of bits), see: web/js/input/input.js.
- Added new `coordintaor.selector` config param that changes the selection algorithm for workers. By default it will select any free worker. Set this param to `ping` for the old behavior.
- Changed the name of the `webrtc.iceServers.url` config param to `webrtc.iceServers.urls`.
2023-01-09 23:20:22 +03:00
Sergey Stepanov
8025cc1d87
Make client ICE logging a bit clearer 2022-07-13 00:00:54 +03:00
Sergey Stepanov
be0e00c7bf
Use display: none in the hide function, so it won't take any space 2022-04-18 22:47:35 +03:00
Sergey Stepanov
ed60ccf41e
Fix visibility of the help overlay 2022-04-18 19:13:26 +03:00
Sergey Stepanov
4baccc4701
Allow adjusting log levels on the fly 2022-04-11 17:46:10 +03:00
Sergey Stepanov
3bbf075f92
Log lines in the browser console 2022-04-11 09:16:08 +03:00
Sergey Stepanov
63d8a0354c
Remove unused CSS in the worker list element 2022-04-09 10:46:10 +03:00
Sergey Stepanov
fac6cc4495
Generate xIds on the worker's side 2022-04-09 10:27:04 +03:00
Sergey Stepanov
c190177955
Show active workers in the debug mode 2022-04-08 20:11:28 +03:00
sergystepanov
9ad3c98a7d
Rework worker selection feature (#365)
We add a new option for manual worker or machine (server with multiple workers) select, depending on the new coordinator option `coordinator.debug` which by default allows machine selection.
2022-04-07 21:04:30 +03:00
Sergey Stepanov
12352d5677
Open GitHub links in a new tab 2022-03-22 22:08:36 +03:00
Sergey Stepanov
3292964f01
Fix pubsub listeners indexing overlap 2022-01-02 06:58:55 +03:00
Sergey Stepanov
24ff0f2ea2
Close WebRTC connections on disconnect
Not closing RTCPeerConnection and co will cause eventually high processor load in Chrome.
Also, Chrome has some GC issues related to WebRTC, see: https://bugs.chromium.org/p/chromium/issues/detail?id=825576.
2021-12-17 16:10:51 +03:00
Sergey Stepanov
535177bd46
Fix recording handling when it's disabled 2021-12-05 22:11:29 +03:00
sergystepanov
1271aa8438
Game recording support (#356)
This feature adds the ability to record game sessions as raw a/v media files.
2021-12-04 14:20:38 +03:00
Sergey Stepanov
b916b0bf19
Add RTT stats 2021-09-02 23:58:05 +03:00
Sergey Stepanov
e7a2b6a33e
Prevent client favicon requests 2021-08-30 16:30:03 +03:00
Sergey Stepanov
9289d9390b
Update stats module 2021-08-28 15:06:51 +03:00
Sergy Stepanov
5199d73caf Show errors when client WS connection fails 2021-07-31 13:05:48 +03:00
Sergy Stepanov
a3d2549028 Remove old is_mobile init param 2021-07-31 12:33:25 +03:00
sergystepanov
54deb3607d
Remove font-awesome CSS ref from the index page 2021-07-30 22:56:16 +03:00
sergystepanov
d3e16a4a09
Make Google Analytics injection optional (#336)
This allows switching GA client statistics on the client by setting these params in the config.yaml file:
 analytics:
   inject: false/true
   gtag: (your tag)
By default, GA analytics will be disabled.
2021-07-30 12:29:16 +03:00
sergystepanov
ff562503f1
Delete not used font-awesome.css 2021-07-30 12:22:59 +03:00
sergystepanov
3abb1d4818
Use orientation-based video / canvas stretching (#335) 2021-07-28 02:13:03 +03:00
sergystepanov
30d104ee98
Add version info into the apps (#330)
Both worker and coordinator display version number in the console during startup. Coordinator displays its version number in the top right corner of the index.html page.
2021-07-16 18:13:20 +03:00
sergystepanov
2378288a5b
Fix player select with touch controls (#325) 2021-07-02 13:34:12 +03:00
Sergey Stepanov
2a1bdbb3c9
Use passive touchstart events
Due to possible scroll blocking.
2021-04-14 11:53:31 +03:00
sergystepanov
7ebd945344
Remove jQuery (#299)
* Remove jQuery

* Remove browser (vendor) prefixes for some CSS properties

* Use simple device orientation test

* Realign D-pad pointers

* Make GameBoy text unselectable

* Cleanup console.log

* Keep 90% size on mobile browsers due to gh-ribbon overlap

* Remove legacy `unselectable="on"` attributes

* Align UI buttons

* Remove not used UI elements

* Change Options button

* Don't show player change message when not in a game

* Add click/touch handler for circle-pad
2021-03-26 11:07:49 +03:00
sergystepanov
d5780acc75
Fix Pion WebRTC codecs (#289)
Since Pion's webrtc v3.0.13 and this fix if both peers have some fmtp set then codecs should match exactly. By default Pion defines a list of supported codecs with fmtp set but different browsers set their own fmtp values by default as well therefore they may not match.
To fix this we can define our own list of codecs on the server with empty fmtp so it will match any client codecs.

See: e5c8c659ca/rtpcodec.go (L99)
2021-03-08 17:22:43 +03:00
sergystepanov
b56069c96e
Fix stream freeze (#279)
* Fix D-pad key and overlay

* Add Video element error reporting

* Terminate clientside ws ping on the connection terminate
2021-02-20 18:45:43 +03:00
Sergey Stepanov
c37c2c3004
Fix D-pad key and overlay 2021-02-20 00:12:05 +03:00
sergystepanov
92d0dd76f4
Refactor input for safe concurrency (#278)
* Extract input stuff

* Move d-pad option into the main screen

* Add mutex lock on the whole input user sessions struct
2021-02-19 20:33:58 +03:00
sergystepanov
c01ddc869b
Don't hide save/load after the help show 2021-02-08 23:24:01 +03:00
sergystepanov
816b210150
Client game screen configuration support (#269)
* Move game screen to a separate [stream] module

* Add a simple canvas video mirror for post-processing

* Add video mirroring to the options
2021-01-25 12:58:05 +03:00
Sergey Stepanov
f7152c7d21
Fix control buttons width 2021-01-18 22:49:47 +03:00
Sergey Stepanov
6f4e27d0fa
Optimize images 2021-01-09 13:55:33 +03:00
sergystepanov
980a97a526
Handle no config situation for workers (#253)
(experimental feature)

Before a worker can start, it should have a configuration file. In case if such a file is not found it may request configuration from the coordinator to which it connected.

Added example logic if a worker is needed to be blocked until a successful packet exchange with a coordinator is being made.

* Add error return for config loader

* Add config loaded flag to worker

* Add zone flag

* Add a custom mutex lock with timout

* Refactor worker runtime

* Refactor internal api

* Extract monitoring server config

* Extract worker HTTP(S) server

* Add generic sub-server interface

* Add internal coordinator API

* Add internal routes and handlers to worker

* Add internal worker API

* Refactor worker run

* Migrate serverId call to new API

* Add packet handler to cws

* Extract handlers for internal worker routes in coordinator

* Pass worker to the worker internal heandlers

* Cleanup worker handlers in coordinator

* Add closeRoom packet handler to the API

* Add GetRoom packet handler to the API

* Add RegisterRoom packet handler to the API

* Add IceCandidate packet handler to the API (internal and browser)

* Add Heartbeat packet handler to the API (internal and browser)

* Rename worker routes init function

* Extract worker/coordinator internal ws handlers

* Update timed locker

* Allow sequential timed locks

* Add config request from workers

* Add nil check for the route registration functions
2021-01-03 21:23:55 +03:00
sergystepanov
1fcf34ee02
Add new Libretro core manager module (#249)
* Add initial external configuration files support.

These external configuration files allow changing app params at the runtime without recompilation.

* Find config files with specified directory in the tests

* Add aspect ratio recalculation config

* Clean code

* Add new configuration files into the Docker container image

* Add shared core and config paths into the Libretro cores config

* Split ROM <-> Emulator mapping between workers and coordinators

* Extract coordinator config

* Add shared worker/coordinator server config

* Add explicit embedded shared worker/coordinator struct for auto-config reflection fill

* Remove default stun/turn servers from the config

* Extract and add new ice servers config structures

* Update coordinator config params

* Add auto emulation lib loader based on the runtime OS/arch

* Update configuration structures

* Remove shared config embedding

* Add missing network config params

* Add game library external config

* Remove unused config parameters

* Add WebRTC encoder external options

* Add user dir for config search

* Update config loader

* Update config

* Add generic downloader with Grab lib implementation

* Add a simple file downloader backed by the grab lib

* Add initial Libretro core repos abstractions

* Expose compression info for Libretro cores repository records

* Add pipe-based abstract file downloader

* Refactor downloader

* Refactor Libretro repos

* Add worker coresync stubs

* Add multiprocess-safe HTTP-based core manager implementation

* Remove Libretro cores from the repo

* Keep custom N64 cores in te repo for now

* Add Libretro cores repo select in the config

* Fix http manager repo switch

* Cleanup code

* Add greedy Libretro lib loader

* Don't crash when arch map is not set

* Disable dynamic recompiler for pcsx core by default since it's could cause a crash

* Use global Libretro dynalib handler

* Shorten the default Libretro cores store path

* Update zip extractor implementation

* Remove explicit fig lib field markings

* Add config note to the README file

* Add GitHub repo backend for the core downloader

* Fix GitHub repo param list in the manager factory

* Add env variables reader with CLOUD_GAME prefix

* Re-optimize ice server info struct custom marshaler
2020-12-31 13:24:27 +03:00
Sergey Stepanov
7299ecc6d1
Add art credits 2020-11-25 20:57:46 +03:00
sergystepanov
8c55c6e142
Fix game sharing (#240)
Call save on the frontend and properly handle cloud save on the backend
2020-10-19 21:26:32 +08:00
sergystepanov
453087ed28
Remove duplicate worker addresses during ping check (client, server) (#234) 2020-10-03 23:53:46 +08:00
sergystepanov
564b96df8d
Add anti-abuse debounce and throttle functions (#233) 2020-10-02 02:16:28 +08:00
giongto35
611a70482a Merge conflict 2020-09-13 03:42:27 +08:00
giongto35
7b736d455e
Merge Pr/173 with master (#218)
* Add the initial support for settings

* Rearrange init order for the settings and log modules

* Add import settings function

* Add initial settings display panel

* Add settings controls

* Add settings controls handlers

* Add garbage gui auto-builder for settings

* Add some custom binding handlers for settings

* Add super ineffective ¯\_(ツ)_/¯ keyboard bindings remap function

* Migrate keyboard to codes instead deprecated keyCodes

* Abort key remap on Esc

Co-authored-by: Sergey Stepanov <sergystepanov@gmail.com>
2020-07-04 04:24:13 +08:00
88hcsif
f7f044d039 Add multitap support to SNES
Change SNES emulator to Snes9X
Add client control to toggle multitap
2020-06-28 23:35:07 +01:00
88hcsif
42514fa09a Swap A and B for PS3 controller
Add PS3 controller mapping for Safari and Firefox
2020-06-28 23:35:06 +01:00
88hcsif
2aa1ae4ecb
Add frame delay or frame rate stats to stat view. (#206)
Unfortunately Firefox does not expose frame delay stat.
Unfortunately Chrome and Safari do not expose frame rate stat.
2020-06-26 02:39:39 +08:00
sergystepanov
36894ad730
Swap the A/B buttons (#209) 2020-06-25 23:06:25 +08:00