# Server

<a id="server-12"></a>

# Server

```cpp
#include <icy/symple/server.h>

class Server
```

[Defined in src/symple/include/icy/symple/server.h:136](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L136)

Symple v4 server.

Accepts WebSocket connections, authenticates peers, manages rooms, and routes messages. Implements the Symple v4 protocol over native WebSocket.

Usage: [smpl::Server](#server-12) server; server.start({.port = 4500});

// Optional: custom authentication server.Authenticate += []([ServerPeer](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer)& peer, const [json::Value](https://auscaster.com/icey/docs/api-reference/icy-json.md#value)& auth, bool& allowed, std::vector<std::string>& rooms) { allowed = (auth.value("token", "") == "secret"); rooms.push_back("team-a"); };

The server also serves as an HTTP server, so you can serve static files (e.g. a web UI) on the same port.

## Friends

| Name | Description |
|------|-------------|
| [`Factory`](#factory-2)  |  |

---

<a id="factory-2"></a>

### Factory

```cpp
friend class Factory
```

[Defined in src/symple/include/icy/symple/server.h:283](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L283)

## Public Attributes

| Return | Name | Description |
|--------|------|-------------|
| [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &, const [`json::Value`](https://auscaster.com/icey/docs/api-reference/icy-json.md#value) &auth, bool &allowed, std::vector< std::string > &rooms)> | [`Authenticate`](#authenticate-2)  | Custom authentication hook. Set `allowed` to false to reject the peer. Append to `rooms` to assign team/group memberships. If not connected, all peers with a valid `user` field are accepted. |
| [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &)> | [`PeerConnected`](#peerconnected-1)  | [Peer](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) authenticated and online. |
| [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &)> | [`PeerDisconnected`](#peerdisconnected-1)  | [Peer](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) disconnected. |

---

<a id="authenticate-2"></a>

### Authenticate

```cpp
Signal< void(ServerPeer &, const json::Value &auth, bool &allowed, std::vector< std::string > &rooms)> Authenticate
```

Type: [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &, const [`json::Value`](https://auscaster.com/icey/docs/api-reference/icy-json.md#value) &auth, bool &allowed, std::vector< std::string > &rooms)>

[Defined in src/symple/include/icy/symple/server.h:217](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L217)

Custom authentication hook. Set `allowed` to false to reject the peer. Append to `rooms` to assign team/group memberships. If not connected, all peers with a valid `user` field are accepted.

---

<a id="peerconnected-1"></a>

### PeerConnected

```cpp
Signal< void(ServerPeer &)> PeerConnected
```

Type: [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &)>

[Defined in src/symple/include/icy/symple/server.h:220](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L220)

[Peer](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) authenticated and online.

---

<a id="peerdisconnected-1"></a>

### PeerDisconnected

```cpp
Signal< void(ServerPeer &)> PeerDisconnected
```

Type: [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal)< void([`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) &)>

[Defined in src/symple/include/icy/symple/server.h:223](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L223)

[Peer](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) disconnected.

## Public Methods

| Return | Name | Description |
|--------|------|-------------|
|  | [`Server`](#server-13)  | Constructs a server using the given event loop. |
|  | [`~Server`](#server-14)  |  |
|  | [`Server`](#server-15)  | Deleted constructor. |
| [`Server`](#server-12) & | [`operator=`](#operator-250)  | Deleted assignment operator. |
| `void` | [`start`](#start-31)  | Starts the server with the given options. Begins accepting WebSocket connections on opts.host:opts.port. |
| `void` | [`start`](#start-32)  | Starts the server with a custom HTTP factory for non-WebSocket requests. The Symple server handles WebSocket upgrades internally; any other HTTP request (e.g. static files, REST API) is delegated to this factory. |
| `void` | [`stop`](#stop-20)  | Broadcasts a shutdown notice to all peers, closes the listen socket, and releases all internal state. Safe to call more than once. |
| `void` | [`broadcast`](#broadcast)  | Broadcast a message to all peers in a room (excluding sender). |
| `void` | [`broadcastRooms`](#broadcastrooms)  | Broadcast to multiple rooms with per-recipient dedup. |
| `bool` | [`sendTo`](#sendto)  | Send a message to a specific peer by session ID. |
| `bool` | [`sendToUser`](#sendtouser)  | Send a message to any peer with the given user name. |
| [`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) * | [`getPeer`](#getpeer)  | Get a connected peer by session ID. |
| std::vector< [`ServerPeer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-ServerPeer.md#serverpeer) * > | [`getPeersInRoom`](#getpeersinroom)  | Get all peers in a room. |
| `size_t` | [`peerCount`](#peercount) `const` | Number of connected, authenticated peers. |
| `void` | [`addVirtualPeer`](#addvirtualpeer)  | Register a virtual peer that receives messages via callback. |
| `void` | [`removeVirtualPeer`](#removevirtualpeer)  | Remove a virtual peer by session ID. |
| [`http::Server`](https://auscaster.com/icey/docs/api-reference/icy-http-Server.md#server) & | [`httpServer`](#httpserver) `inline` | Access the underlying HTTP server (e.g. to serve static files). |
| [`uv::Loop`](https://auscaster.com/icey/docs/api-reference/uv.md#loop-1) * | [`loop`](#loop-10) `const` `inline` | [Event](https://auscaster.com/icey/docs/api-reference/icy-smpl-Event.md#event-2) loop that owns the Symple server and all peer connections. |

---

<a id="server-13"></a>

### Server

```cpp
Server(uv::Loop * loop = uv::defaultLoop())
```

[Defined in src/symple/include/icy/symple/server.h:161](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L161)

Constructs a server using the given event loop.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `loop` | [`uv::Loop`](https://auscaster.com/icey/docs/api-reference/uv.md#loop-1) * | libuv event loop; defaults to [uv::defaultLoop()](https://auscaster.com/icey/docs/api-reference/uv.md#defaultloop). |

---

<a id="server-14"></a>

### ~Server

```cpp
~Server()
```

[Defined in src/symple/include/icy/symple/server.h:162](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L162)

---

<a id="server-15"></a>

### Server

```cpp
Server(const Server &) = delete
```

[Defined in src/symple/include/icy/symple/server.h:164](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L164)

Deleted constructor.

---

<a id="operator-250"></a>

### operator=

```cpp
Server & operator=(const Server &) = delete
```

[Defined in src/symple/include/icy/symple/server.h:165](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L165)

Deleted assignment operator.

---

<a id="start-31"></a>

### start

```cpp
void start(const Options & opts)
```

[Defined in src/symple/include/icy/symple/server.h:170](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L170)

Starts the server with the given options. Begins accepting WebSocket connections on opts.host:opts.port.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `opts` | const [`Options`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-Options.md#options-17) & | [Server](#server-12) configuration options. |

---

<a id="start-32"></a>

### start

```cpp
void start(const Options & opts, std::unique_ptr< http::ServerConnectionFactory > httpFactory)
```

[Defined in src/symple/include/icy/symple/server.h:177](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L177)

Starts the server with a custom HTTP factory for non-WebSocket requests. The Symple server handles WebSocket upgrades internally; any other HTTP request (e.g. static files, REST API) is delegated to this factory.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `opts` | const [`Options`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-Options.md#options-17) & | [Server](#server-12) configuration options. |
| `httpFactory` | std::unique_ptr< [`http::ServerConnectionFactory`](https://auscaster.com/icey/docs/api-reference/icy-http-ServerConnectionFactory.md#serverconnectionfactory) > | Factory for HTTP responders; may be nullptr. |

---

<a id="stop-20"></a>

### stop

```cpp
void stop()
```

[Defined in src/symple/include/icy/symple/server.h:182](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L182)

Broadcasts a shutdown notice to all peers, closes the listen socket, and releases all internal state. Safe to call more than once.

---

<a id="broadcast"></a>

### broadcast

```cpp
void broadcast(const std::string & room, const json::Value & msg, const std::string & excludeId = {})
```

[Defined in src/symple/include/icy/symple/server.h:186](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L186)

Broadcast a message to all peers in a room (excluding sender).

---

<a id="broadcastrooms"></a>

### broadcastRooms

```cpp
void broadcastRooms(const std::unordered_set< std::string > & rooms, const json::Value & msg, const std::string & excludeId = {})
```

[Defined in src/symple/include/icy/symple/server.h:190](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L190)

Broadcast to multiple rooms with per-recipient dedup.

---

<a id="sendto"></a>

### sendTo

```cpp
bool sendTo(const std::string & peerId, const json::Value & msg)
```

[Defined in src/symple/include/icy/symple/server.h:195](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L195)

Send a message to a specific peer by session ID.

---

<a id="sendtouser"></a>

### sendToUser

```cpp
bool sendToUser(const std::string & user, const json::Value & msg)
```

[Defined in src/symple/include/icy/symple/server.h:198](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L198)

Send a message to any peer with the given user name.

---

<a id="getpeer"></a>

### getPeer

```cpp
ServerPeer * getPeer(const std::string & id)
```

[Defined in src/symple/include/icy/symple/server.h:201](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L201)

Get a connected peer by session ID.

---

<a id="getpeersinroom"></a>

### getPeersInRoom

```cpp
std::vector< ServerPeer * > getPeersInRoom(const std::string & room)
```

[Defined in src/symple/include/icy/symple/server.h:204](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L204)

Get all peers in a room.

---

<a id="peercount"></a>

### peerCount

`const`

```cpp
size_t peerCount() const
```

[Defined in src/symple/include/icy/symple/server.h:207](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L207)

Number of connected, authenticated peers.

---

<a id="addvirtualpeer"></a>

### addVirtualPeer

```cpp
void addVirtualPeer(const Peer & peer, const std::vector< std::string > & rooms, std::function< void(const json::Value &)> handler)
```

[Defined in src/symple/include/icy/symple/server.h:234](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L234)

Register a virtual peer that receives messages via callback.

The virtual peer appears in presence broadcasts and is routable like any WebSocket-connected peer. Messages addressed to it are delivered via the callback instead of a WebSocket connection.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `peer` | const [`Peer`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) & | [Peer](https://auscaster.com/icey/docs/api-reference/icy-smpl-Peer.md#peer-1) data (must have "id", "user", "name" fields). |
| `rooms` | `const std::vector< std::string > &` | Rooms the virtual peer joins. |
| `handler` | std::function< void(const [`json::Value`](https://auscaster.com/icey/docs/api-reference/icy-json.md#value) &)> | Called when a message is routed to this peer. |

---

<a id="removevirtualpeer"></a>

### removeVirtualPeer

```cpp
void removeVirtualPeer(const std::string & peerId)
```

[Defined in src/symple/include/icy/symple/server.h:239](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L239)

Remove a virtual peer by session ID.

---

<a id="httpserver"></a>

### httpServer

`inline`

```cpp
inline http::Server & httpServer()
```

[Defined in src/symple/include/icy/symple/server.h:242](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L242)

Access the underlying HTTP server (e.g. to serve static files).

---

<a id="loop-10"></a>

### loop

`const` `inline`

```cpp
inline uv::Loop * loop() const
```

[Defined in src/symple/include/icy/symple/server.h:245](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L245)

[Event](https://auscaster.com/icey/docs/api-reference/icy-smpl-Event.md#event-2) loop that owns the Symple server and all peer connections.

## Private Attributes

| Return | Name | Description |
|--------|------|-------------|
| [`Options`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-Options.md#options-17) | [`_opts`](#_opts)  |  |
| [`uv::Loop`](https://auscaster.com/icey/docs/api-reference/uv.md#loop-1) * | [`_loop`](#_loop-3)  |  |
| std::unique_ptr< [`http::Server`](https://auscaster.com/icey/docs/api-reference/icy-http-Server.md#server) > | [`_http`](#_http)  |  |
| std::unique_ptr< [`PeerRegistry`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-PeerRegistry.md#peerregistry) > | [`_peerRegistry`](#_peerregistry)  |  |
| std::unique_ptr< [`RoomIndex`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-RoomIndex.md#roomindex) > | [`_roomIndex`](#_roomindex)  |  |
| `std::mutex` | [`_mutex`](#_mutex-23)  |  |
| `std::atomic< bool >` | [`_shuttingDown`](#_shuttingdown)  |  |
| std::unique_ptr< [`http::ServerConnectionFactory`](https://auscaster.com/icey/docs/api-reference/icy-http-ServerConnectionFactory.md#serverconnectionfactory) > | [`_httpFallback`](#_httpfallback)  | Fallback factory for non-WebSocket HTTP requests. |

---

<a id="_opts"></a>

### _opts

```cpp
Options _opts
```

Type: [`Options`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-Options.md#options-17)

[Defined in src/symple/include/icy/symple/server.h:271](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L271)

---

<a id="_loop-3"></a>

### _loop

```cpp
uv::Loop * _loop = nullptr
```

Type: [`uv::Loop`](https://auscaster.com/icey/docs/api-reference/uv.md#loop-1) *

[Defined in src/symple/include/icy/symple/server.h:272](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L272)

---

<a id="_http"></a>

### _http

```cpp
std::unique_ptr< http::Server > _http
```

Type: std::unique_ptr< [`http::Server`](https://auscaster.com/icey/docs/api-reference/icy-http-Server.md#server) >

[Defined in src/symple/include/icy/symple/server.h:273](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L273)

---

<a id="_peerregistry"></a>

### _peerRegistry

```cpp
std::unique_ptr< PeerRegistry > _peerRegistry
```

Type: std::unique_ptr< [`PeerRegistry`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-PeerRegistry.md#peerregistry) >

[Defined in src/symple/include/icy/symple/server.h:274](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L274)

---

<a id="_roomindex"></a>

### _roomIndex

```cpp
std::unique_ptr< RoomIndex > _roomIndex
```

Type: std::unique_ptr< [`RoomIndex`](https://auscaster.com/icey/docs/api-reference/icy-smpl-Server-RoomIndex.md#roomindex) >

[Defined in src/symple/include/icy/symple/server.h:275](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L275)

---

<a id="_mutex-23"></a>

### _mutex

```cpp
std::mutex _mutex
```

[Defined in src/symple/include/icy/symple/server.h:277](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L277)

---

<a id="_shuttingdown"></a>

### _shuttingDown

```cpp
std::atomic< bool > _shuttingDown {false}
```

[Defined in src/symple/include/icy/symple/server.h:278](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L278)

---

<a id="_httpfallback"></a>

### _httpFallback

```cpp
std::unique_ptr< http::ServerConnectionFactory > _httpFallback
```

Type: std::unique_ptr< [`http::ServerConnectionFactory`](https://auscaster.com/icey/docs/api-reference/icy-http-ServerConnectionFactory.md#serverconnectionfactory) >

[Defined in src/symple/include/icy/symple/server.h:281](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L281)

Fallback factory for non-WebSocket HTTP requests.

## Private Methods

| Return | Name | Description |
|--------|------|-------------|
| `void` | [`onAuth`](#onauth)  |  |
| `void` | [`onMessage`](#onmessage)  |  |
| `void` | [`onJoin`](#onjoin)  |  |
| `void` | [`onLeave`](#onleave)  |  |
| `void` | [`onDisconnect`](#ondisconnect)  |  |
| `void` | [`route`](#route)  |  |
| `bool` | [`deliver`](#deliver)  |  |
| `bool` | [`deliverSerialized`](#deliverserialized)  |  |
| `void` | [`sendPresenceSnapshot`](#sendpresencesnapshot)  |  |

---

<a id="onauth"></a>

### onAuth

```cpp
void onAuth(ServerPeer & peer, const json::Value & msg, std::unique_lock< std::mutex > & lock)
```

[Defined in src/symple/include/icy/symple/server.h:256](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L256)

---

<a id="onmessage"></a>

### onMessage

```cpp
void onMessage(ServerPeer & peer, json::Value msg)
```

[Defined in src/symple/include/icy/symple/server.h:257](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L257)

---

<a id="onjoin"></a>

### onJoin

```cpp
void onJoin(ServerPeer & peer, const std::string & room)
```

[Defined in src/symple/include/icy/symple/server.h:258](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L258)

---

<a id="onleave"></a>

### onLeave

```cpp
void onLeave(ServerPeer & peer, const std::string & room)
```

[Defined in src/symple/include/icy/symple/server.h:259](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L259)

---

<a id="ondisconnect"></a>

### onDisconnect

```cpp
void onDisconnect(ServerPeer & peer, std::unique_lock< std::mutex > & lock)
```

[Defined in src/symple/include/icy/symple/server.h:260](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L260)

---

<a id="route"></a>

### route

```cpp
void route(ServerPeer & sender, const json::Value & msg)
```

[Defined in src/symple/include/icy/symple/server.h:261](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L261)

---

<a id="deliver"></a>

### deliver

```cpp
bool deliver(const std::string & peerId, const json::Value & msg)
```

[Defined in src/symple/include/icy/symple/server.h:262](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L262)

---

<a id="deliverserialized"></a>

### deliverSerialized

```cpp
bool deliverSerialized(const std::string & peerId, const char * data, size_t len, const json::Value & msg)
```

[Defined in src/symple/include/icy/symple/server.h:263](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L263)

---

<a id="sendpresencesnapshot"></a>

### sendPresenceSnapshot

```cpp
void sendPresenceSnapshot(ServerPeer & recipient, const std::unordered_set< std::string > & rooms, std::string_view excludeId = {})
```

[Defined in src/symple/include/icy/symple/server.h:267](https://github.com/auscaster/icey/blob/main/src/symple/include/icy/symple/server.h#L267)
