Commit graph

72 commits

Author SHA1 Message Date
sergystepanov
57168067d9 Guard remote ICE candidates against null peer connection 2026-06-09 20:00:51 +03:00
sergystepanov
7442ff7e42 Reset ICE buffering on the client on ICE restarts 2026-06-09 15:10:08 +03:00
sergystepanov
86ee0cb380 Create the main data channel without negotiation
There is no point in previously pushing or pulling this channel, since we won't change any of its configuration parameters.
2026-06-09 15:10:07 +03:00
sergystepanov
c5886c5b1b Add connection time logging to WebRTC handler 2026-06-08 16:47:18 +03:00
sergystepanov
fa783dc7cd Add init method into WebRTC Signalling 2026-06-06 14:20:17 +03:00
sergystepanov
eaed44a03f Add direct siganlling dependency in the WebRTC module 2026-06-06 11:51:51 +03:00
sergystepanov
3388a0fbce Create data channels when pushed to the server 2026-06-05 14:46:55 +03:00
sergystepanov
d9a13f006c Disable renegotiation when ICE fails 2026-06-04 23:11:45 +03:00
sergystepanov
4dfc001a76 Exit when peer connection is not set 2026-06-04 22:50:48 +03:00
sergystepanov
d6f2cfc5ef Add the option switch for WebRTC initiator 2026-06-04 22:36:36 +03:00
sergystepanov
8c4b4bf96f Add an option for initiating WebRTC offer on the client side
WebRTC negotiation will start in the browser with an offer. Added because a reversed negotiation (server's offer) doesn't work in Firefox-based browsers.
2026-06-04 22:36:35 +03:00
sergystepanov
f6a933799f Change WEBRTC_SDP event naming 2026-06-04 22:36:34 +03:00
sergystepanov
35a23224ab Set ICE prefetch 2026-06-04 22:36:33 +03:00
sergystepanov
c5b7748f95 Close connection when rtc state changes 2026-06-04 22:36:33 +03:00
sergystepanov
637fd81452 Detach WebRTC handlers before close 2026-06-04 22:36:33 +03:00
sergystepanov
8c890f0c8e Clean webrtc.js 2026-06-04 22:36:33 +03:00
sergystepanov
fb926e6d2d Push WEBRTC_READY when connected 2026-06-04 22:36:32 +03:00
sergystepanov
5757e3bac6 Push ICE candidates right away 2026-06-04 22:36:32 +03:00
sergystepanov
7c604e94fb Reformat socket.js 2026-06-04 22:36:31 +03:00
sergystepanov
a8f4860b35 Fix close binding 2026-06-04 22:36:31 +03:00
sergystepanov
df8d35f542 Clean WebRTC export 2026-06-04 22:36:31 +03:00
sergystepanov
f50b37c11f Update webrtc.js 2026-06-04 22:36:30 +03:00
sergystepanov
2273fe393f Add IceRestart stub 2026-06-04 22:36:30 +03:00
sergystepanov
65d74bb769 Move MediaStream element to WebRTC start options 2026-06-04 22:36:30 +03:00
sergystepanov
6a03b65e42 Update webrtc.js 2026-06-04 22:36:30 +03:00
sergystepanov
edb92b8993 Change predefined datachannels to callbacks 2026-06-04 22:36:30 +03:00
sergystepanov
de24654ca8 Use direct FlushCandidates instead of global messaging 2026-06-04 22:36:30 +03:00
sergystepanov
dae0b62eb0 Clean webrtc module 2026-06-04 22:36:30 +03:00
sergystepanov
00b52dde8d Reformat webrtc.js 2026-06-04 22:36:29 +03:00
sergystepanov
d42ad68ef3 Add api base64 decoder 2026-06-04 22:36:29 +03:00
sergystepanov
8faa698edc Flush ICE candidates only once 2026-06-04 22:36:29 +03:00
sergystepanov
e6258f11a1 Add readable message logging 2026-06-04 22:36:29 +03:00
sergystepanov
98449d0099 Remove WS message logging 2026-06-01 14:00:22 +03:00
sergystepanov
92f3e6378f Update WebRTC module state logging 2026-06-01 13:56:17 +03:00
sergystepanov
4c699d634b Inline start/stop webrtc methods 2026-06-01 13:45:02 +03:00
sergystepanov
440102fc1b Add more debug methods to WebRTC module 2026-06-01 12:12:26 +03:00
Sergey Stepanov
7ee98c1b03 Add keyboard and mouse support
Keyboard and mouse controls will now work if you use the kbMouseSupport parameter in the config for Libretro cores. Be aware that capturing mouse and keyboard controls properly is only possible in fullscreen mode.

Note: In the case of DOSBox, a virtual filesystem handler is not yet implemented, thus each game state will be shared between all rooms (DOS game instances) of CloudRetro.
2024-08-02 11:04:44 +03:00
Sergey Stepanov
a013192bf8 Clean webrtc.js 2024-04-22 11:47:46 +03:00
Sergey Stepanov
cebbcdf256 Refactor WebRTC stats 2024-04-02 21:10:05 +03:00
Sergey Stepanov
104498dec0
Fix wrong import order of some modules 2024-03-18 13:45:01 +03:00
Sergey Stepanov
2bc64a3be8 Migrate from IIFE to modern ES modules
These modules should be supported by all contemporary browsers, and this transition should resolve most issues related to the explicit import order of the .js files.
2024-03-17 22:09:43 +03:00
Sergey Stepanov
cdbb5e98f5
Clean 2024-03-02 16:46:08 +03:00
Sergey Stepanov
41bfe4f4d3
Fix WebRTC datachannels in FF 2024-02-20 21:29:57 +03:00
Sergey Stepanov
2e91feb861 Add initial automatic aspect ratio change
Depending on the configuration param coreAspectRatio, video streams may have automatic aspect ratio correction in the browser with the value provided by the cores themselves.
2023-11-03 01:12:22 +03:00
Sergey Stepanov
624eecd4e8
Show errors when ICE fails 2023-05-17 08:57:16 +03:00
Sergey Stepanov
229cd4044c
Fix broken warning in the wrtc js module 2023-04-24 14:16:25 +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
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