Skip to content

Commit

Permalink
Unity SDK - Watch GameServer Functionality
Browse files Browse the repository at this point in the history
Able to use the `DownloadHandlerScript` to intercept streaming HTTP
data from the /watch/gameserver REST endpoint.

This finishes the feature work for Unity on #927
  • Loading branch information
markmandel committed Dec 18, 2019
1 parent 85d836d commit 35f9017
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
18 changes: 15 additions & 3 deletions examples/unity-simple/Assets/Scripts/UdpEchoServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async void Start()
Debug.Log(("Server - Failed to connect, exiting"));
Application.Quit(1);
}

ok = await agones.Ready();
if (ok)
{
Expand Down Expand Up @@ -79,13 +79,20 @@ async void Update()
Application.Quit();
return;

case "Ready":
ok = await agones.Ready();
Debug.Log($"Server - Ready {ok}");

echoBytes = Encoding.UTF8.GetBytes($"Ready {ok}");
break;

case "Allocate":
ok = await agones.Allocate();
Debug.Log($"Server - Allocate {ok}");

echoBytes = Encoding.UTF8.GetBytes($"Allocate {ok}");
break;

case "GameServer":
var gameserver = await agones.GameServer();
Debug.Log($"Server - GameServer {gameserver}");
Expand All @@ -107,6 +114,7 @@ async void Update()
{
echoBytes = Encoding.UTF8.GetBytes($"ERROR: Invalid Label command, must use 2 arguments");
}

break;

case "Annotation":
Expand All @@ -129,14 +137,18 @@ async void Update()
TimeSpan duration = new TimeSpan(0, 0, Int32.Parse(recvTexts[1]));
ok = await agones.Reserve(duration);
Debug.Log($"Server - Reserve({recvTexts[1]} {ok}");

echoBytes = Encoding.UTF8.GetBytes($"Reserve({recvTexts[1]}) {ok}");
}
else
{
echoBytes = Encoding.UTF8.GetBytes($"ERROR: Invalid Reserve command, must use 1 argument");
}
break;
case "Watch":
agones.WatchGameServer(gameServer => Debug.Log($"Server - Watch {gameServer}"));
echoBytes = Encoding.UTF8.GetBytes("Watching()");
break;
default:
echoBytes = Encoding.UTF8.GetBytes($"Echo : {recvText}");
break;
Expand Down
43 changes: 43 additions & 0 deletions sdks/unity/AgonesSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,26 @@ public async Task<bool> Reserve(TimeSpan duration)
string json = JsonUtility.ToJson(new Duration(seconds: duration.Seconds));
return await SendRequestAsync("/reserve", json).ContinueWith(task => task.Result.ok);
}

/// <summary>
/// WatchGameServerCallback is the callback that will be executed every time
/// a GameServer is changed and WatchGameServer is notified
/// </summary>
/// <param name="gameServer">The GameServer value</param>
public delegate void WatchGameServerCallback(GameServer gameServer);

/// <summary>
/// WatchGameServer watches for changes in the backing GameServer configuration.
/// </summary>
/// <param name="callback">This callback is executed whenever a GameServer configuration change occurs</param>
public void WatchGameServer(WatchGameServerCallback callback)
{
var req = new UnityWebRequest(sidecarAddress + "/watch/gameserver", UnityWebRequest.kHttpVerbGET);
req.downloadHandler = new GameServerHandler(callback);
req.SetRequestHeader("Content-Type", "application/json");
req.SendWebRequest();
Log("Agones Watch Started");
}
#endregion

#region AgonesRestClient Private Methods
Expand Down Expand Up @@ -325,6 +345,29 @@ private void OnRequestCompleted(AsyncOperation _)
continuation = null;
}
}

/// <summary>
/// Custom UnityWebRequest http data handler
/// that fires a callback whenever it receives data
/// from the SDK.Watch() REST endpoint
/// </summary>
private class GameServerHandler : DownloadHandlerScript
{
private WatchGameServerCallback callback;
public GameServerHandler(WatchGameServerCallback callback)
{
this.callback = callback;
}

protected override bool ReceiveData(byte[] data, int dataLength)
{
string json = Encoding.UTF8.GetString(data);
var dictionary = (Dictionary<string, object>) Json.Deserialize(json);
var gameServer = new GameServer(dictionary["result"] as Dictionary<string, object>);
this.callback(gameServer);
return true;
}
}
#endregion
}
}
14 changes: 12 additions & 2 deletions site/content/en/docs/Guides/Client SDKs/unity.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ description: "This is the Unity version of the Agones Game Server Client SDK."
---

{{< alert title="Note" color="info" >}}
The Unity SDK is functional, but not yet feature complete.
[Pull requests](https://github.com/googleforgames/agones/pulls) to finish the functionality are appreciated.
The Unity SDK is not feature complete in 1.2.0, but will be feature complete with the 1.3.0 release.
{{< /alert >}}

Check the [Client SDK Documentation]({{< relref "_index.md" >}}) for more details on each of the SDK functions and how to run the SDK locally.
Expand Down Expand Up @@ -73,6 +72,17 @@ Similarly `SetAnnotation(string key, string value)` and `SetLabel(string key, st

And there is no need to call `Health()`, it is automatically called.

{{% feature publishVersion="1.3.0" %}}
To watch when
[the backing `GameServer` configuration changes]({{< relref "_index.md#watchgameserver-function-gameserver" >}})
call `WatchGameServer(callback)`, where the delegate function `callback` will be executed every time the `GameServer`
configuration changes.

```csharp
agones.WatchGameServer(gameServer => { Debug.Log($"Server - Watch {gameServer}"); });
```
{{% /feature %}}

{{% alert title="Warning" color="warning"%}}
The following code causes deadlock. Do not use a `Wait` method with the returned Task.
```csharp
Expand Down

0 comments on commit 35f9017

Please sign in to comment.