# Sgcwebsockets P2p

> sgcWebSockets P2P and WebRTC

- Skill: `esegece-com/sgcwebsockets-p2p` (Agent Skill, multi-file: 162 files)
- Install (CLI): `npx skillmds@latest add esegece-com/sgcwebsockets-p2p`
- Raw SKILL.md: https://api.skillmd.com/api/skills/esegece-com/sgcwebsockets-p2p/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: esegece-com (https://skillmd.com/u/esegece-com)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/esegece-com/sgcwebsockets-p2p

---


# sgcWebSockets P2P and WebRTC

Eight components for peer-to-peer connectivity: the NAT traversal building
blocks (STUN, TURN, ICE), a WebRTC peer connection, and two signalling servers.

Two peers behind home routers cannot address each other directly. These
components are the standard machinery for getting around that, and they layer:
STUN discovers your public address, TURN relays when discovery is not enough,
ICE tries the candidates in order, and the peer connection uses whichever won.

## When to use this skill

- Find out what public address and port a NAT has assigned you
- Relay media or data through a TURN server when direct connection fails
- Gather and test ICE candidates
- Establish a WebRTC peer connection from Delphi
- Run the signalling server that lets two peers exchange offers and answers
- Run your own STUN or TURN server

## Units

Six of the eight are in `sgcP2P`:

```pascal
uses
  sgcP2P;   // STUN client and server, TURN client and server,
            // ICE client, RTCPeerConnection
```

The two signalling servers, `TsgcWSPServer_WebRTC` and
`TsgcWSPServer_RTCPeerConnection`, are WebSocket protocol components and live in
`sgcWebSocket_Protocols`. They attach to a WebSocket server through `Server`,
like the other protocol components in `sgcwebsockets-protocols`.

## Before you start, ask the developer

Use a structured question tool if your host has one, for example Claude Code's
`AskUserQuestion`. Otherwise ask in chat:

1. **Which layer do you actually need?** Asking "how do I do WebRTC" usually
   means the peer connection plus a signalling server. Asking "what is my public
   IP" is just the STUN client, which is far less work.
2. **Are both peers Delphi, or is one a browser?** A browser peer constrains the
   signalling format, because the browser's `RTCPeerConnection` expects standard
   SDP offers and answers.
3. **Do you have a TURN server, or do you need to run one?** Relaying costs
   bandwidth on whoever hosts it, so this is a deployment decision, not just a
   code one.
4. **Is a public STUN server acceptable?** Many projects use a public one for
   discovery and only self-host TURN.

## Components in this skill

| Component | Layer | Use it for |
| --- | --- | --- |
| `TsgcSTUNClient` | STUN | Discover the public address a NAT gives you |
| `TsgcSTUNServer` | STUN | Run your own STUN service |
| `TsgcTURNClient` | TURN | Allocate a relay and send through it |
| `TsgcTURNServer` | TURN | Run your own relay |
| `TsgcICEClient` | ICE | Gather and prioritise connection candidates |
| `TsgcRTCPeerConnection` | WebRTC | The peer connection itself |
| `TsgcWSPServer_WebRTC` | signalling | Signalling server for WebRTC peers |
| `TsgcWSPServer_RTCPeerConnection` | signalling | Signalling for peer connections |

## Quickstart, what is my public address

The simplest useful thing here, and often all that is wanted:

```pascal
uses
  sgcP2P;

FSTUN := TsgcSTUNClient.Create(Self);
if FSTUN.SendBindingRequest('stun.l.google.com', 19302) then
  // the mapped address arrives through the component's events
  ;
```

`GetLocalSocketBinding` gives you the local side of the same socket, which is
what you compare against to work out whether you are behind a NAT at all.

## Quickstart, TURN relay

TURN is allocate, then keep alive, then send. The allocation expires, so the
refresh is not optional:

```pascal
FTURN := TsgcTURNClient.Create(Self);
FTURN.Allocate;
FTURN.Refresh(600);                       // lifetime in seconds
FTURN.SendIndication('203.0.113.5', 50000, vData);

// or bind a channel first, which is cheaper per message
FTURN.ChannelBind('203.0.113.5', 50000);
FTURN.SendChannelData(vChannelId, vData);
```

Send indications carry the peer address on every message. A bound channel
carries a small channel id instead, so use `ChannelBind` and `SendChannelData`
when you are sending steadily to one peer.

## Quickstart, WebRTC offer and answer

The peer connection follows the standard WebRTC handshake. One side offers, the
other answers, and both gather candidates. Signalling, the business of getting
the offer to the other peer, is what the signalling servers are for:

```pascal
FPeer := TsgcRTCPeerConnection.Create(Self);
FPeer.GatherCandidates;
FPeer.CreateOffer;          // the offer arrives through an event, send it on
// ... the far side calls CreateAnswer and returns its SDP ...
FPeer.WriteData('hello over the data channel');
```

`CreateOffer` and `CreateAnswer` do not return the SDP directly. It reaches you
through an event, because gathering is asynchronous.

## Things that catch people out

- WebRTC needs signalling and the WebRTC standard does not define it. If two
  peers never connect, the offer or the answer is usually not reaching the other
  side, and the peer connection code is fine.
- A TURN allocation expires. Call `Refresh` well before the lifetime you asked
  for elapses, or the relay drops and the symptom looks like a network fault.
- STUN alone is not enough behind symmetric NAT. That is precisely the case
  TURN exists for, so plan for a relay rather than assuming discovery suffices.
- The signalling servers are protocol components. They need `Server` assigned
  to a WebSocket server, and without it they do nothing and raise nothing.
- Candidate gathering is asynchronous. Acting on the offer immediately after
  calling `CreateOffer` gets you an incomplete candidate list.

## Routing

- **Find a component**: `reference/components-index.md` lists every component, its `unit`, and its edition, grouped by Reg module.
- **Uses clause**: add the component's `unit:` value (shown on its API page) to your `uses` clause. Nothing compiles without it.
- **API detail**: `reference/api/<Component>.md` has the Properties, Events and Methods, each in both Delphi and C++Builder form.
- **Option / enum / event types**: property and event types link to `reference/types/<TypeName>.md`, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers.
- **Examples**: `examples/index.md` is the full demo catalog; `examples/<Component>.md` is a focused, real usage snippet for the most-used components.
- **Concepts**: `concepts/overview.md` (getting started + uses-clause rule) and `concepts/editions-and-features.md` (which components your edition includes).
- **Bundled resources**: `concepts/resources.md` lists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN.
- **Version history**: `reference/history.md` lists what changed in each sgcWebSockets release.

## Editions

Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or `concepts/editions-and-features.md`, before relying on a component.

Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.


