### Server-Side Implementation Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Example Node.js server setup using socket.io to handle authentication and event communication. ```javascript const port = 11100; const io = require('socket.io')(); io.use((socket, next) => { if (socket.handshake.query.token === "UNITY") { next(); } else { next(new Error("Authentication error")); } }); io.on('connection', socket => { socket.emit('connection', {date: new Date().getTime(), data: "Hello Unity"}) socket.on('hello', (data) => { socket.emit('hello', {date: new Date().getTime(), data: data}); }); socket.on('spin', (data) => { socket.emit('spin', {date: new Date().getTime()}); }); socket.on('class', (data) => { socket.emit('class', {date: new Date().getTime(), data: data}); }); }); io.listen(port); console.log('listening on *:' + port); ``` -------------------------------- ### Multiplayer Game Manager Implementation Source: https://context7.com/itisnajim/socketiounity/llms.txt A MonoBehaviour class that handles socket initialization, event subscription, and game object synchronization. Ensure the SocketIOClient and Newtonsoft.Json packages are installed in your Unity project. ```csharp using System; using System.Collections.Generic; using SocketIOClient; using SocketIOClient.Newtonsoft.Json; using UnityEngine; using UnityEngine.UI; public class MultiplayerGameManager : MonoBehaviour { public static MultiplayerGameManager Instance { get; private set; } private SocketIOUnity socket; [Header("Connection Settings")] public string serverUrl = "http://localhost:11100"; public string authToken = "UNITY"; [Header("UI References")] public Text connectionStatusText; public Text latencyText; [Header("Game Objects")] public GameObject playerPrefab; public Transform spawnPoint; private Dictionary remotePlayers = new Dictionary(); void Awake() { Instance = this; DontDestroyOnLoad(gameObject); } void Start() { InitializeSocket(); SetupEventHandlers(); Connect(); } void InitializeSocket() { socket = new SocketIOUnity(new Uri(serverUrl), new SocketIOOptions { Query = new Dictionary { {"token", authToken} }, EIO = EngineIO.V4, Transport = SocketIOClient.Transport.TransportProtocol.WebSocket, Reconnection = true, ReconnectionAttempts = 5, ReconnectionDelay = 2000 }, UnityThreadScope.Update); socket.JsonSerializer = new NewtonsoftJsonSerializer(); } void SetupEventHandlers() { // Connection lifecycle socket.OnConnected += (s, e) => UpdateConnectionStatus("Connected"); socket.OnDisconnected += (s, reason) => UpdateConnectionStatus($"Disconnected: {reason}"); socket.OnReconnectAttempt += (s, attempt) => UpdateConnectionStatus($"Reconnecting ({attempt})..."); socket.OnPong += (s, latency) => UpdateLatency(latency); // Game events - all on Unity thread for safe GameObject access socket.OnUnityThread("playerJoined", OnPlayerJoined); socket.OnUnityThread("playerLeft", OnPlayerLeft); socket.OnUnityThread("playerMoved", OnPlayerMoved); socket.OnUnityThread("gameState", OnGameStateReceived); } void Connect() { UpdateConnectionStatus("Connecting..."); socket.Connect(); } void UpdateConnectionStatus(string status) { if (connectionStatusText != null) connectionStatusText.text = status; Debug.Log($"[Network] {status}"); } void UpdateLatency(TimeSpan latency) { if (latencyText != null) latencyText.text = $"Ping: {latency.TotalMilliseconds:F0}ms"; } // Event Handlers void OnPlayerJoined(SocketIOResponse response) { var player = response.GetValue(); if (!remotePlayers.ContainsKey(player.id)) { var playerObj = Instantiate(playerPrefab, new Vector3(player.x, player.y, player.z), Quaternion.identity); playerObj.name = $"Player_{player.id}"; remotePlayers[player.id] = playerObj; Debug.Log($"Player joined: {player.name}"); } } void OnPlayerLeft(SocketIOResponse response) { string playerId = response.GetValue(); if (remotePlayers.TryGetValue(playerId, out GameObject playerObj)) { Destroy(playerObj); remotePlayers.Remove(playerId); Debug.Log($"Player left: {playerId}"); } } void OnPlayerMoved(SocketIOResponse response) { var movement = response.GetValue(); if (remotePlayers.TryGetValue(movement.playerId, out GameObject playerObj)) { playerObj.transform.position = new Vector3(movement.x, movement.y, movement.z); playerObj.transform.rotation = Quaternion.Euler(0, movement.rotation, 0); } } void OnGameStateReceived(SocketIOResponse response) { var state = response.GetValue(); Debug.Log($"Game state received: {state.players.Length} players"); } // Public API for sending events public void SendMovement(Vector3 position, float rotation) { socket.Emit("move", new PlayerMovement { playerId = socket.Id, x = position.x, y = position.y, z = position.z, rotation = rotation }); } public void SendChatMessage(string message) { socket.Emit("chat", new ChatMessage { playerId = socket.Id, text = message, timestamp = DateTime.UtcNow }); } async void OnApplicationQuit() { if (socket != null && socket.Connected) { await socket.DisconnectAsync(); } ``` -------------------------------- ### Initialize SocketIOUnity Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Configure the socket connection with a URI, query parameters, and transport protocol. ```csharp var uri = new Uri("https://www.example.com"); socket = new SocketIOUnity(uri, new SocketIOOptions { Query = new Dictionary { {"token", "UNITY" } } , Transport = SocketIOClient.Transport.TransportProtocol.WebSocket }); ``` -------------------------------- ### Create Socket Connection with Options Source: https://context7.com/itisnajim/socketiounity/llms.txt Establishes a Socket.IO connection with configurable options like authentication, transport protocol, and reconnection settings. Ensure to use a JSON serializer compatible with IL2CPP. ```csharp using System; using System.Collections.Generic; using SocketIOClient; using SocketIOClient.Newtonsoft.Json; using UnityEngine; public class GameNetworkManager : MonoBehaviour { private SocketIOUnity socket; void Start() { // Basic connection var uri = new Uri("http://localhost:11100"); // Connection with full options socket = new SocketIOUnity(uri, new SocketIOOptions { // Authentication query parameters Query = new Dictionary { {"token", "UNITY"}, {"playerId", "player123"} }, // Socket.IO server version (V3 or V4) EIO = EngineIO.V4, // Transport protocol (WebSocket recommended for games) Transport = SocketIOClient.Transport.TransportProtocol.WebSocket, // Reconnection settings Reconnection = true, ReconnectionAttempts = 10, ReconnectionDelay = 1000, ReconnectionDelayMax = 5000, // Connection timeout ConnectionTimeout = TimeSpan.FromSeconds(20), // Custom path (if server uses non-default path) Path = "/socket.io", // Optional: HTTP headers ExtraHeaders = new Dictionary { {"Authorization", "Bearer your-token"} } }, UnityThreadScope.Update); // Use Newtonsoft.Json for IL2CPP compatibility socket.JsonSerializer = new NewtonsoftJsonSerializer(); socket.Connect(); } } ``` -------------------------------- ### Configure JSON Serializer Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Switch from the default System.Text.Json to Newtonsoft Json.Net to avoid IL2CPP compatibility issues. ```csharp socket.JsonSerializer = new NewtonsoftJsonSerializer(); ``` -------------------------------- ### Managing Socket Connections Source: https://context7.com/itisnajim/socketiounity/llms.txt Establish connections using synchronous or asynchronous methods and ensure proper disposal on application exit. ```csharp public class ConnectionManager : MonoBehaviour { private SocketIOUnity socket; void Start() { InitializeSocket(); } void InitializeSocket() { var uri = new Uri("http://localhost:11100"); socket = new SocketIOUnity(uri, new SocketIOOptions { Query = new Dictionary { {"token", "UNITY"} }, EIO = EngineIO.V4, Transport = SocketIOClient.Transport.TransportProtocol.WebSocket }); // Synchronous connect (fire-and-forget) socket.Connect(); // Check connection status Debug.Log($"Connected: {socket.Connected}"); Debug.Log($"Socket ID: {socket.Id}"); } // Async connection with error handling async void ConnectAsync() { try { await socket.ConnectAsync(); Debug.Log("Connected successfully!"); } catch (SocketIOClient.Exceptions.ConnectionException ex) { Debug.LogError($"Connection failed: {ex.Message}"); } } // Synchronous disconnect public void Disconnect() { socket.Disconnect(); } // Async disconnect async void OnApplicationQuit() { if (socket != null && socket.Connected) { await socket.DisconnectAsync(); } socket?.Dispose(); } void OnDestroy() { socket?.Dispose(); } } ``` -------------------------------- ### Emit Events with SocketIOUnity Source: https://context7.com/itisnajim/socketiounity/llms.txt Demonstrates various ways to send events, including simple messages, serialized objects, acknowledgment callbacks, and asynchronous patterns. ```csharp public class EventEmitter : MonoBehaviour { private SocketIOUnity socket; void SendEvents() { // Simple event without data socket.Emit("ping"); // Event with string data socket.Emit("message", "Hello Server!"); // Event with multiple parameters socket.Emit("move", "player1", 10.5f, 20.3f); // Event with object (auto-serialized to JSON) var playerData = new PlayerState { name = "Player1", position = new Vector3Data { x = 10, y = 0, z = 5 }, health = 100 }; socket.Emit("playerUpdate", playerData); // Event with acknowledgment callback socket.Emit("createRoom", (response) => { var roomId = response.GetValue(); Debug.Log($"Room created with ID: {roomId}"); }, "GameRoom1"); // Send raw JSON string directly socket.EmitStringAsJSON("customEvent", "{\"action\":\"jump\",\"force\":10}"); } // Async versions for await pattern async void SendEventsAsync() { await socket.EmitAsync("asyncEvent", "data"); await socket.EmitAsync("requestData", (response) => { var result = response.GetValue(); Debug.Log($"Received: {result}"); }, "query"); } [System.Serializable] public class PlayerState { public string name; public Vector3Data position; public int health; } [System.Serializable] public class Vector3Data { public float x, y, z; } } ``` -------------------------------- ### Connect and Disconnect Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Manage the socket connection lifecycle using synchronous or asynchronous methods. ```csharp socket.Connect(); await socket.ConnectAsync(); socket.Disconnect(); await socket.DisconnectAsync(); ``` -------------------------------- ### Configure Newtonsoft.Json for IL2CPP builds Source: https://context7.com/itisnajim/socketiounity/llms.txt Assign a NewtonsoftJsonSerializer instance to the socket to ensure compatibility with IL2CPP environments. ```csharp using SocketIOClient.Newtonsoft.Json; using Newtonsoft.Json; public class JsonSerializerSetup : MonoBehaviour { private SocketIOUnity socket; void SetupNewtonsoftSerializer() { var uri = new Uri("http://localhost:11100"); socket = new SocketIOUnity(uri); // Basic Newtonsoft.Json setup (recommended for IL2CPP) socket.JsonSerializer = new NewtonsoftJsonSerializer(); // Advanced: Custom JsonSerializerSettings var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ", Formatting = Formatting.None }; socket.JsonSerializer = new NewtonsoftJsonSerializer(settings); socket.Connect(); } // Example with complex nested objects void SendComplexData() { var gameState = new GameState { timestamp = System.DateTime.UtcNow, players = new Player[] { new Player { id = "p1", name = "Alice", score = 100 }, new Player { id = "p2", name = "Bob", score = 85 } }, settings = new GameSettings { difficulty = "hard", maxPlayers = 4 } }; socket.Emit("gameState", gameState); } [System.Serializable] public class GameState { public System.DateTime timestamp; public Player[] players; public GameSettings settings; } [System.Serializable] public class Player { public string id; public string name; public int score; } [System.Serializable] public class GameSettings { public string difficulty; public int maxPlayers; } } ``` -------------------------------- ### Implementing Request-Response with Acknowledgments Source: https://context7.com/itisnajim/socketiounity/llms.txt Use Emit with a callback for client-side requests and CallbackAsync within OnUnityThread for server-side requests. ```csharp public class AcknowledgmentHandler : MonoBehaviour { private SocketIOUnity socket; void RequestWithAck() { // Client sends request, server responds with acknowledgment socket.Emit("joinRoom", (response) => { bool success = response.GetValue(0); string message = response.GetValue(1); if (success) { Debug.Log($"Joined room: {message}"); } else { Debug.LogError($"Failed to join: {message}"); } }, "room-123", "PlayerName"); // Server sends event, client responds with acknowledgment socket.OnUnityThread("serverRequest", async (response) => { var request = response.GetValue(); // Process request and send response back to server var result = new ClientResponse { success = true, data = "Processed successfully" }; await response.CallbackAsync(result); }); } [System.Serializable] public class ServerRequest { public string action; public string[] parameters; } [System.Serializable] public class ClientResponse { public bool success; public string data; } } ``` -------------------------------- ### Implement Node.js Socket.IO Server Source: https://context7.com/itisnajim/socketiounity/llms.txt A Socket.IO server implementation featuring authentication middleware, player management, and event handling for movement and chat. ```javascript // server.js - Node.js Socket.IO server const http = require('http'); const { Server } = require('socket.io'); const server = http.createServer(); const io = new Server(server, { pingInterval: 10000, pingTimeout: 5000, cors: { origin: "*" } }); // Authentication middleware io.use((socket, next) => { const token = socket.handshake.query.token; if (token === "UNITY") { next(); } else { next(new Error("Authentication error")); } }); const players = new Map(); io.on('connection', (socket) => { console.log(`Player connected: ${socket.id}`); // Send welcome message socket.emit('connection', { date: Date.now(), data: "Hello Unity", socketId: socket.id }); // Handle player join socket.on('join', (playerData) => { players.set(socket.id, { ...playerData, id: socket.id }); socket.broadcast.emit('playerJoined', players.get(socket.id)); // Send current game state to new player socket.emit('gameState', { players: Array.from(players.values()), serverTime: Date.now() }); }); // Handle movement socket.on('move', (data) => { socket.broadcast.emit('playerMoved', data); }); // Handle chat socket.on('chat', (message) => { io.emit('chat', message); }); // Handle disconnect socket.on('disconnect', () => { players.delete(socket.id); io.emit('playerLeft', socket.id); console.log(`Player disconnected: ${socket.id}`); }); }); const PORT = 11100; server.listen(PORT, () => { console.log(`Socket.IO server running on port ${PORT}`); }); ``` -------------------------------- ### Receive Events on Unity Thread Source: https://context7.com/itisnajim/socketiounity/llms.txt Shows how to use OnUnityThread to safely interact with Unity components like Transforms and UI elements when receiving socket events. ```csharp public class EventReceiver : MonoBehaviour { private SocketIOUnity socket; public Transform playerTransform; public Text statusText; public GameObject effectPrefab; void SetupEventHandlers() { // Configure which Unity lifecycle to use for callbacks socket.unityThreadScope = UnityThreadScope.Update; // or LateUpdate, FixedUpdate // Safe to modify Unity objects in this callback socket.OnUnityThread("playerMoved", (response) => { var position = response.GetValue(); playerTransform.position = new Vector3(position.x, position.y, position.z); }); // Update UI safely socket.OnUnityThread("scoreUpdate", (response) => { int score = response.GetValue(); statusText.text = $"Score: {score}"; }); // Spawn game objects socket.OnUnityThread("spawnEffect", (response) => { var data = response.GetValue(); Instantiate(effectPrefab, new Vector3(data.x, data.y, data.z), Quaternion.identity); }); // Access multiple values from response socket.OnUnityThread("multiData", (response) => { string eventType = response.GetValue(0); int count = response.GetValue(1); var details = response.GetValue(2); Debug.Log($"Type: {eventType}, Count: {count}"); }); } [System.Serializable] public class PositionData { public float x, y, z; } [System.Serializable] public class SpawnData { public float x, y, z; public string type; } [System.Serializable] public class EventDetails { public string name; public int value; } } ``` -------------------------------- ### Receive Events Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Listen for incoming events from the server and process the response data. ```csharp socket.On("eventName", (response) => { /* Do Something with data! */ var obj = response.GetValue(); ... }); ``` -------------------------------- ### Define Unity Network Data Classes Source: https://context7.com/itisnajim/socketiounity/llms.txt Serializable classes for representing network players, movement, chat messages, and game state in Unity. ```csharp [Serializable] public class NetworkPlayer { public string id; public string name; public float x, y, z; } [Serializable] public class PlayerMovement { public string playerId; public float x, y, z, rotation; } [Serializable] public class ChatMessage { public string playerId; public string text; public DateTime timestamp; } [Serializable] public class GameState { public NetworkPlayer[] players; public int serverTime; } ``` -------------------------------- ### Handle Socket Connection Events Source: https://context7.com/itisnajim/socketiounity/llms.txt Sets up event handlers for monitoring the socket connection lifecycle, including connection, disconnection, reconnections, errors, and heartbeat events. Debug logs indicate the status of these events. ```csharp public class ConnectionHandler : MonoBehaviour { private SocketIOUnity socket; void SetupConnectionEvents() { // Fired when connection is established socket.OnConnected += (sender, e) => { Debug.Log($"Connected! Socket ID: {socket.Id}"); Debug.Log($"Connected: {socket.Connected}"); }; // Fired when disconnected from server socket.OnDisconnected += (sender, reason) => { // Reasons: "io server disconnect", "io client disconnect", // "ping timeout", "transport close", "transport error" Debug.Log($"Disconnected: {reason}"); }; // Fired on each reconnection attempt socket.OnReconnectAttempt += (sender, attemptNumber) => { Debug.Log($"Reconnecting... Attempt #{attemptNumber}"); }; // Fired after successful reconnection socket.OnReconnected += (sender, attemptNumber) => { Debug.Log($"Reconnected after {attemptNumber} attempts"); }; // Fired when reconnection attempt fails socket.OnReconnectError += (sender, exception) => { Debug.LogError($"Reconnect error: {exception.Message}"); }; // Fired when all reconnection attempts exhausted socket.OnReconnectFailed += (sender, e) => { Debug.LogError("Failed to reconnect to server"); }; // Fired when server sends error socket.OnError += (sender, errorMessage) => { Debug.LogError($"Server error: {errorMessage}"); }; // Heartbeat events socket.OnPing += (sender, e) => Debug.Log("Ping sent"); socket.OnPong += (sender, latency) => Debug.Log($"Pong received: {latency.TotalMilliseconds}ms"); } } ``` -------------------------------- ### Handle Unity Threading Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Execute socket event callbacks on the Unity main thread to safely interact with GameObjects. ```csharp // Set (unityThreadScope) the thread scope function where the code should run. // Options are: .Update, .LateUpdate or .FixedUpdate, default: UnityThreadScope.Update socket.unityThreadScope = UnityThreadScope.Update; // "spin" is an example of an event name. socket.OnUnityThread("spin", (response) => { objectToSpin.transform.Rotate(0, 45, 0); }); ``` ```csharp socket.On("spin", (response) => { UnityThread.executeInUpdate(() => { objectToSpin.transform.Rotate(0, 45, 0); }); /* or UnityThread.executeInLateUpdate(() => { ... }); or UnityThread.executeInFixedUpdate(() => { ... }); */ }); ``` -------------------------------- ### Emit Events Source: https://github.com/itisnajim/socketiounity/blob/main/README.md Send data to the server using various emit methods, including support for callbacks and asynchronous operations. ```csharp socket.Emit("eventName"); socket.Emit("eventName", "Hello World"); socket.Emit("eventName", someObject); socket.Emit("eventName",(response)=>{ string text = response.GetValue(); print(text); }, someObject); socket.EmitStringAsJSON("eventName", "{\"foo\": \"bar\"}"); await client.EmitAsync("hi", "socket.io"); // Here you should make the method async ``` -------------------------------- ### Registering Background Event Handlers in C# Source: https://context7.com/itisnajim/socketiounity/llms.txt Use On for background thread processing and OnAnyInUnityThread for safe Unity API access. Ensure UnityThread.executeInUpdate is used if background handlers need to interact with Unity objects. ```csharp public class BackgroundEventHandler : MonoBehaviour { private SocketIOUnity socket; void SetupBackgroundHandlers() { // Background thread handler - DO NOT access Unity API directly here socket.On("dataReceived", (response) => { // Process data on background thread var data = response.GetValue(); ProcessDataInBackground(data); // If you need Unity API, use UnityThread.executeInUpdate UnityThread.executeInUpdate(() => { Debug.Log($"Processed: {data.name}"); }); }); // Remove handler when no longer needed socket.Off("dataReceived"); // Listen to ALL events with OnAny socket.OnAny((eventName, response) => { Debug.Log($"Event '{eventName}' received: {response.GetValue().GetRawText()}"); }); // OnAny with Unity thread safety socket.OnAnyInUnityThread((eventName, response) => { // Safe to use Unity API here Debug.Log($"[Unity Thread] {eventName}: {response.Count} items"); }); } void ProcessDataInBackground(GameData data) { // CPU-intensive work here won't block Unity } [System.Serializable] public class GameData { public string name; public int[] values; } } ``` -------------------------------- ### Execute Unity API calls from background threads Source: https://context7.com/itisnajim/socketiounity/llms.txt Use UnityThread static methods to marshal actions from socket event callbacks to the main thread, FixedUpdate, or LateUpdate loops. ```csharp public class ThreadingExample : MonoBehaviour { private SocketIOUnity socket; public Transform target; public Text statusLabel; void SetupWithManualThreading() { // Using On (background thread) with manual Unity thread execution socket.On("updatePosition", (response) => { var pos = response.GetValue(); // Execute in next Update() call UnityThread.executeInUpdate(() => { target.position = new Vector3(pos.x, pos.y, pos.z); }); }); socket.On("physicsUpdate", (response) => { var data = response.GetValue(); // Execute in next FixedUpdate() - ideal for physics UnityThread.executeInFixedUpdate(() => { target.GetComponent().AddForce( new Vector3(data.forceX, data.forceY, data.forceZ) ); }); }); socket.On("cameraUpdate", (response) => { var data = response.GetValue(); // Execute in next LateUpdate() - ideal for camera UnityThread.executeInLateUpdate(() => { Camera.main.transform.position = new Vector3(data.x, data.y, data.z); }); }); // Execute coroutine from background thread socket.On("loadAsset", (response) => { string assetPath = response.GetValue(); UnityThread.executeCoroutine(LoadAssetCoroutine(assetPath)); }); } System.Collections.IEnumerator LoadAssetCoroutine(string path) { var request = Resources.LoadAsync(path); yield return request; Debug.Log($"Asset loaded: {request.asset.name}"); } [System.Serializable] public class Position { public float x, y, z; } [System.Serializable] public class PhysicsData { public float forceX, forceY, forceZ; } [System.Serializable] public class CameraData { public float x, y, z; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.