https://github.com/mazyod/phoenixsharp
C# Phoenix Channels client. Unity Compatible.
https://github.com/mazyod/phoenixsharp
csharp networking phoenix phoenix-framework presence realtime unity unity3d websockets
Last synced: 4 months ago
JSON representation
C# Phoenix Channels client. Unity Compatible.
- Host: GitHub
- URL: https://github.com/mazyod/phoenixsharp
- Owner: Mazyod
- License: mit
- Created: 2016-11-24T19:47:16.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2026-01-30T15:18:13.000Z (5 months ago)
- Last Synced: 2026-01-31T07:06:50.711Z (5 months ago)
- Topics: csharp, networking, phoenix, phoenix-framework, presence, realtime, unity, unity3d, websockets
- Language: C#
- Homepage:
- Size: 822 KB
- Stars: 171
- Watchers: 8
- Forks: 28
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
A C# client for Phoenix Channels.
Unity compatible. Powering Dama King.
---
## Features
- Full [Phoenix Channels](https://hexdocs.pm/phoenix/channels.html) protocol support
- Modern async/await API with cancellation support
- Automatic reconnection and channel rejoin
- Presence tracking
- Customizable WebSocket and JSON implementations
- Unity and .NET Standard 2.0 compatible
## Installation
### NuGet
```bash
dotnet add package PhoenixSharp
```
### Unity (OpenUPM)
Install via [openupm-cli](https://github.com/openupm/openupm-cli#openupm-cli):
```bash
openupm add io.level3.phoenixsharp
```
Or add manually to `Packages/manifest.json`:
```json
{
"scopedRegistries": [
{
"name": "package.openupm.com",
"url": "https://package.openupm.com",
"scopes": ["io.level3"]
}
],
"dependencies": {
"io.level3.phoenixsharp": "1.3.1"
}
}
```
Alternatively, download the source and add it to your project, or use a Git submodule.
## Quick Start
```csharp
// Create and connect a socket
var socket = new Socket(
"wss://example.com/socket",
new Socket.Options(new JsonMessageSerializer())
);
socket.Connect();
// Join a channel
var channel = socket.Channel("room:lobby", new { userId = "123" });
channel.Join();
// Listen for events
channel.On("new_message", message => {
var payload = message.Payload.Unbox();
Console.WriteLine($"Received: {payload.Text}");
});
// Send messages
channel.Push("send_message", new { text = "Hello!" });
```
### Async API
```csharp
await socket.ConnectAsync();
var result = await channel.JoinAsync();
if (result.IsSuccess)
{
var response = await channel.PushAsync(
"send_message",
new { text = "Hello!" }
);
if (response.IsSuccess)
Console.WriteLine($"Sent with id: {response.Response.Id}");
}
await channel.LeaveAsync();
```
## Documentation
- [Migration Guide](https://github.com/Mazyod/PhoenixSharp/blob/master/Migration.md) - Upgrading from older versions
- [Integration Tests](PhoenixTests/IntegrationTests.cs) - Complete usage examples
### WebSocket Implementation
The library requires an `IWebsocket` implementation. Sample implementations are available in [`PhoenixTests/WebSocketImpl`](PhoenixTests/WebSocketImpl).
```csharp
var factory = new MyWebSocketFactory();
var socket = new Socket(address, null, factory, options);
```
**Recommended implementations:**
- **BestHTTP** (Unity) - See [`Reference/Unity/BestHTTP`](Reference/Unity/BestHTTP)
- **WebSocketSharp** - Good cross-platform option
- **System.Net.WebSockets** - Built-in .NET option
### JSON Serialization
The default `JsonMessageSerializer` uses [Newtonsoft.Json](https://www.newtonsoft.com/json) with the [Phoenix V2 serialization format](https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/socket/serializers/v2_json_serializer.ex). To use a different serializer, implement `IMessageSerializer` and `IJsonBox`.
```csharp
var options = new Socket.Options(new MyCustomSerializer());
```
### Presence
```csharp
var presence = new Presence(channel);
presence.OnJoin += (key, current, newPresence) => {
Console.WriteLine($"{key} joined");
};
presence.OnLeave += (key, current, leftPresence) => {
Console.WriteLine($"{key} left");
};
// Wait for initial state (async)
await presence.WaitForInitialSyncAsync();
```
## Unity Notes
For background on Unity's .NET support, see [Microsoft's Unity scripting documentation](https://docs.microsoft.com/en-us/visualstudio/gamedev/unity/unity-scripting-upgrade).
### Threading
By default, callbacks use `System.Threading.Tasks` which works with Unity's `SynchronizationContext`. For more control, implement `IDelayedExecutor` (or use [UniTask](https://github.com/Cysharp/UniTask) for better performance):
```csharp
var options = new Socket.Options(serializer)
{
DelayedExecutor = new CoroutineDelayedExecutor()
};
```
See [`Reference/Unity`](Reference/Unity) for a coroutine-based implementation.
### Recommended Libraries
- **[BestHTTP](https://assetstore.unity.com/packages/tools/network/best-http-2-155981)** - Handles threading automatically
- **[com.unity.nuget.newtonsoft-json](https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.2/manual/index.html)** - Unity's official Newtonsoft.Json package
## API Reference
### Socket
| Method | Description |
|--------|-------------|
| `Connect()` | Connect to the server |
| `ConnectAsync()` | Connect asynchronously |
| `Disconnect()` | Disconnect from the server |
| `DisconnectAsync()` | Disconnect asynchronously |
| `Channel(topic, params)` | Create a channel |
### Channel
| Method | Description |
|--------|-------------|
| `Join()` | Join the channel |
| `JoinAsync()` | Join asynchronously, returns `JoinResult` |
| `Leave()` | Leave the channel |
| `LeaveAsync()` | Leave asynchronously |
| `Push(event, payload)` | Send a message |
| `PushAsync(event, payload)` | Send asynchronously, returns `PushResult` |
| `PushAsync(event, payload)` | Send with typed response |
| `On(event, callback)` | Subscribe to events |
| `Off(event)` | Unsubscribe from events |
| `WaitForEventAsync(event)` | Wait for a single event |
### Presence
| Method | Description |
|--------|-------------|
| `OnJoin` | Event fired when a user joins |
| `OnLeave` | Event fired when a user leaves |
| `OnSync` | Event fired on state sync |
| `WaitForInitialSyncAsync()` | Wait for initial presence state |
| `WaitForUserAsync(key, timeout)` | Wait for a specific user |
## Running Tests
```bash
# All tests
dotnet test
# Unit tests only
dotnet test --filter "Category!=Integration"
# Integration tests (requires server)
dotnet test --filter "Category=Integration"
```
Integration tests run against `phoenix-sharp.level3.io:3080`. Server source: [phoenix-integration-tester](https://github.com/Mazyod/phoenix-integration-tester)
## Contributing
Issues and pull requests are welcome!
## License
MIT
## Author
Maz (Mazyad Alabduljaleel)
---
Logo is a mix of Unity and Phoenix logos. Please don't sue me.