using ReadyPlayerMe.Core; using System; using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Text; using UnityEngine; public class ServerSocket : MonoBehaviour { private TcpListener _server; private TcpClient _client; private NetworkStream _stream; private bool _isRunning = false; private ConcurrentQueue messageQueue = new ConcurrentQueue(); // Thread-safe queue public event Action OnMessageReceived; public void StartServer(int port) { try { _server = new TcpListener(IPAddress.Any, port); _server.Start(); _isRunning = true; Debug.Log("Server socket started. Waiting for client..."); _server.BeginAcceptTcpClient(OnClientConnected, null); } catch (Exception ex) { Debug.LogError("Server error: " + ex.Message); } } void OnClientConnected(IAsyncResult result) { if (!_isRunning) return; _client = _server.EndAcceptTcpClient(result); _stream = _client.GetStream(); Debug.Log("Client connected!"); ReceiveMessage(); } void ReceiveMessage() { if (_stream == null || !_stream.CanRead) return; // Prevent issues if the stream is closed byte[] buffer = new byte[1024]; _stream.BeginRead(buffer, 0, buffer.Length, ar => { try { int bytesRead = _stream.EndRead(ar); if (bytesRead > 0) { string responseText = Encoding.UTF8.GetString(buffer, 0, bytesRead); MessageInfo message = JsonUtility.FromJson(responseText); messageQueue.Enqueue(message); } // Closing current connection _client.Close(); _stream.Close(); _server.BeginAcceptTcpClient(OnClientConnected, null); } catch (Exception ex) { Debug.LogError("Error reading from stream: " + ex.Message); } }, null); } public void SendSocketMessage(string message) { if (_stream != null && _stream.CanWrite) { byte[] buffer = Encoding.UTF8.GetBytes(message); _stream.BeginWrite(buffer, 0, buffer.Length, OnWriteComplete, null); Debug.Log("Message sent: " + message); } } private void OnWriteComplete(IAsyncResult ar) { try { _stream.EndWrite(ar); // Completes the async write operation Debug.Log("Message write completed."); } catch (Exception ex) { Debug.LogError("Error writing to stream: " + ex.Message); } } void OnDestroy() { // TODO: Close the server socket only when the entire application was closed, not only the current scene //isRunning = false; //stream?.Close(); //client?.Close(); //server?.Stop(); } private void Update() { // Process messages from the queue on the main thread if (messageQueue.TryDequeue(out MessageInfo message)) { OnMessageReceived?.Invoke(message); } } } [Serializable] public class MessageInfo { public DateTime time; public string source; public string destination; public string body; public MessageInfo(DateTime time, string source, string destination, string body) { this.time = time; this.source = source; this.destination = destination; this.body = body; } }