S&box Wiki

Revision Difference

websockets#560457

<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");⤶ }⤶ }⤶ ```⤶ ⤶ ⤶ ## 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 Sandbox.Services.GetToken( "YourServiceName" );⤶ ⤶ 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 );⤶ ```⤶ <note>Page needs to be entirely rewritten for the scene system, lets wait until networking is more finalized though.</note>