Revision Difference
websockets#551665
<cat>Code.Network</cat>
<title>Websockets</title>
# Why and What
Websockets enable bidirectional communication between a client and a server, meaning that both can send and receive data at any time, without the need for the client to make repeated requests to the server. If you are looking to make HTTP-like requests, you can use the [dedicated API](https://wiki.facepunch.com/sbox/http).
# Examples
## Basic Example
This can be called on client or server. But normally you would only start a websocket on the server and have the client interface with the server which then uses your websocket.
```csharp
using Sandbox;
using Sandbox.UI.Construct;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
public class Backend: Entity
{
public Backend() {
socket = new WebSocket(); // Initialize your websocket
}
public WebSocket socket = null;
// Send a simple object over websocket
private async Task SendMessage() {
string payload = "my data";
// Send the message
await socket.Send(payload);
}
// Handle Received Messages
private void HandleMessageReceived(string data) {
Log.Info(data);
}
// Connect to your backend service
private async Task ConnectToBackend() {
// Add function to handle received messages
socket.OnMessageReceived += HandleMessageReceived;
// Connect!
await socket.Connect("wss://your-websocket-endpoint");
}
}
```
⤶
<note>Websocket URLs are also affected by the [HTTP allowlist](https://wiki.facepunch.com/sbox/http#allowlist)</note>⤶
⤶
## Advanced Example
⤶
⤶
## Advanced Example
This example is [hasura](https://hasura.io/) and [graphql](https://graphql.org/) backend specific. But you can edit to match whatever protocol you are connecting to. This can be as simple as just sending and receiving text from a backend service as shown above.
```csharp
using Sandbox;
using Sandbox.UI.Construct;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
public class Backend: Entity
{
public Backend() {
socket = new WebSocket(); // Initialize your websocket
}
public WebSocket socket = null;
// Send a simple object over websocket
private async Task SendMessage() {
var randomPayload = new {
message: "how cool"
};
// Serialize an object to a string to send over the websocket
string jsonString = JsonSerializer.Serialize(randomPayload);
// Send the message
await socket.Send(jsonString);
}
// Handle Received Messages
private void HandleMessageReceived(string data) {
Log.Info(data);
}
private async Task ConnectToBackend() {
// Set your socket protocol
socket.AddSubProtocol("graphql-ws");
// Add function to handle received messages
socket.OnMessageReceived += HandleMessageReceived;
// Connect!
await socket.Connect("wss://your-websocket-endpoint");
// My protocol requires an initial connection payload to fully connect to backend
var connectionPayload = new {
type = "connection_init",
payload = new {
lazy = true,
}
};
// Serialize an object to a string to send over the websocket
string jsonString = JsonSerializer.Serialize(connectionPayload);
await socket.Send(jsonString);
}
}
```
# Using Auth Tokens
You could attach an [Auth Token](AuthTokens) to your websocket request header like so:
```csharp
var token = await Auth.GetToken( "YourGameService" );
if ( string.IsNullOrEmpty( token ) )
{
Log.Info( "Unable to fetch a valid session token..." );
return;
}
var headers = new Dictionary<string, string>()
{
{ "Authorization", token }
};
await socket.Connect( "ws://localhost:8080", headers );
```