Samples~/SampleGame/Assets/Scripts/Client/NetworkClient.cs (177 lines of code) (raw):
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
#if !UNITY_SERVER
using System;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
public class NetworkClient
{
public const string LocalHost = "localhost";
private readonly GameLogic _gl;
private TcpClient _client = null;
public bool Authoritative => _client == null;
public NetworkClient(GameLogic gl)
{
_gl = gl;
}
public void Update()
{
if (_client == null)
{
return;
}
string[] messages = NetworkProtocol.Receive(_client);
foreach (string msgStr in messages)
{
_gl.Log.WriteLine("Msg rcvd: " + msgStr);
HandleMessage(msgStr);
}
}
public bool TryConnect(ConnectionInfo connectionInfo)
{
try
{
_client = new TcpClient(connectionInfo.IpAddress, connectionInfo.Port);
string msgStr = "CONNECT:" + connectionInfo.Serialize();
NetworkProtocol.Send(_client, msgStr);
return true;
}
catch (ArgumentNullException e)
{
_client = null;
_gl.Log.WriteLine(":( CONNECT TO SERVER " + connectionInfo.IpAddress + " FAILED: " + e);
return false;
}
catch (SocketException e) // server not available
{
_client = null;
if (connectionInfo.IpAddress == LocalHost)
{
_gl.Log.WriteLine(":) CONNECT TO LOCAL SERVER FAILED: PROBABLY NO LOCAL SERVER RUNNING, TRYING GAMELIFT");
}
else
{
_gl.Log.WriteLine(":( CONNECT TO SERVER " + connectionInfo.IpAddress + "FAILED: " + e + " (ARE YOU ON THE *AMAZON*INTERNAL*NETWORK*?)");
}
return false;
}
}
public void Ready()
{
if (_client == null)
{
return;
}
string msgStr = "READY:";
try
{
NetworkProtocol.Send(_client, msgStr);
}
catch (SocketException e)
{
HandleDisconnect();
_gl.Log.WriteLine("Ready failed: Disconnected" + e);
}
}
public void TransmitInput(int playerIdx, Chord chord)
{
if (_client == null)
{
return;
}
string msgStr = "INPUT:" + chord.Serialize();
try
{
NetworkProtocol.Send(_client, msgStr);
}
catch (SocketException e)
{
HandleDisconnect();
_gl.Log.WriteLine("TransmitInput failed: Disconnected" + e);
}
}
public void End()
{
if (_client == null)
{
return;
}
string msgStr = "END:";
try
{
NetworkProtocol.Send(_client, msgStr);
}
catch (SocketException e)
{
HandleDisconnect();
_gl.Log.WriteLine("End failed: Disconnected" + e);
}
}
public void Disconnect()
{
if (_client == null)
{
return;
}
string msgStr = "DISCONNECT:";
try
{
NetworkProtocol.Send(_client, msgStr);
}
finally
{
HandleDisconnect();
}
}
private void HandleMessage(string msgStr)
{
// parse message and pass json string to relevant handler for deserialization
//gl.log.WriteLine("Msg rcvd:" + msgStr);
string delimiter = ":";
string json = msgStr.Substring(msgStr.IndexOf(delimiter) + delimiter.Length);
if (msgStr[0] == 'S')
{
HandleState(json);
}
if (msgStr[0] == 'L')
{
HandleLog(json);
}
if (msgStr[0] == 'R')
{
HandleReject();
}
if (msgStr[0] == 'D')
{
HandleDisconnect();
}
}
private void HandleState(string msgStr)
{
_gl.SetState(msgStr);
}
private void HandleLog(string msgStr)
{
_gl.Log.WriteLine(msgStr);
}
private void HandleReject()
{
_gl.Log.WriteLine(":( CONNECT TO SERVER REJECTED: game already full");
NetworkStream stream = _client.GetStream();
stream.Close();
_client.Close();
_client = null;
_gl.ClientConnected = false;
}
private void HandleDisconnect()
{
_gl.EndGame();
if (_client.Connected)
{
NetworkStream stream = _client.GetStream();
stream.Close();
}
_client.Close();
_client = null;
_gl.ClientConnected = false;
}
}
#endif