1+ using Google . Protobuf ;
2+ using GameWorkstore . Patterns ;
3+ using System ;
4+ using System . Collections ;
5+ using System . Text ;
6+ using UnityEngine . Networking ;
7+ using System . Collections . Generic ;
8+
9+ namespace GameWorkstore . AsyncNetworkEngine
10+ {
11+ public enum CloudProvider
12+ {
13+ GCP = 0 ,
14+ AWS = 1
15+ }
16+
17+ public static class AsyncNetworkEngineMap
18+ {
19+ internal static bool IsSingleCloud = true ;
20+ internal static CloudProvider SingleCloudProvider = CloudProvider . AWS ;
21+ internal static Dictionary < string , CloudProvider > MapCloudProvider = null ;
22+
23+ /// <summary>
24+ /// Setup a single cloud provider for all functions.
25+ /// </summary>
26+ /// <param name="cloudProvider">Target cloud provider implementation.</param>
27+ public static void SetupCloud ( CloudProvider cloudProvider )
28+ {
29+ IsSingleCloud = true ;
30+ SingleCloudProvider = cloudProvider ;
31+ }
32+
33+ /// <summary>
34+ /// Setup a multi cloud provider for all functions.
35+ /// </summary>
36+ /// <param name="mapCloudProvider">Maps base url to cloud provider. Use the lowest possible string to differentiate clouds.</param>
37+ public static void SetupCloudMap ( Dictionary < string , CloudProvider > mapCloudProvider )
38+ {
39+ IsSingleCloud = false ;
40+ MapCloudProvider = mapCloudProvider ;
41+ }
42+ }
43+
44+ /// <summary>
45+ /// Implements a UnityRequest for google protobuf web functions.
46+ /// </summary>
47+ /// <typeparam name="TR">Request</typeparam>
48+ /// <typeparam name="TU">Response</typeparam>
49+ public static class AsyncNetworkEngine < TR , TU >
50+ where TR : IMessage < TR > , new ( )
51+ where TU : IMessage < TU > , new ( )
52+ {
53+ private static readonly MessageParser < TU > _tuParser = new MessageParser < TU > ( ( ) => new TU ( ) ) ;
54+ private static readonly MessageParser < GenericErrorResponse > _tvParser = new MessageParser < GenericErrorResponse > ( ( ) => new GenericErrorResponse ( ) ) ;
55+ private static EventService _eventService = null ;
56+
57+ public static void Send ( string uri , TR request , Action < Transmission , TU , GenericErrorResponse > result )
58+ {
59+ if ( _eventService == null ) _eventService = ServiceProvider . GetService < EventService > ( ) ;
60+ _eventService . StartCoroutine ( SendRequest ( uri , request , result ) ) ;
61+ }
62+
63+ public static IEnumerator SendRequest ( string uri , TR request , Action < Transmission , TU , GenericErrorResponse > result )
64+ {
65+ //Notice: APIGateway automatically converts binary data into base64 strings
66+ using var rqt = new UnityWebRequest ( uri , "POST" )
67+ {
68+ uploadHandler = new UploadHandlerRaw ( request . ToByteArray ( ) ) ,
69+ downloadHandler = new DownloadHandlerBuffer ( )
70+ } ;
71+ yield return rqt . SendWebRequest ( ) ;
72+
73+ switch ( rqt . result )
74+ {
75+ case UnityWebRequest . Result . ConnectionError :
76+ Return ( Transmission . ErrorConnection , result ) ;
77+ break ;
78+ case UnityWebRequest . Result . ProtocolError :
79+ HandleError ( GetCloudProvider ( ref uri ) , rqt , result ) ;
80+ break ;
81+ case UnityWebRequest . Result . Success :
82+ while ( ! rqt . downloadHandler . isDone ) yield return null ;
83+ HandleSuccess ( GetCloudProvider ( ref uri ) , rqt , result ) ;
84+ break ;
85+ }
86+ }
87+
88+ private static CloudProvider GetCloudProvider ( ref string url )
89+ {
90+ if ( ! AsyncNetworkEngineMap . IsSingleCloud )
91+ {
92+ foreach ( var pair in AsyncNetworkEngineMap . MapCloudProvider )
93+ {
94+ if ( ! url . StartsWith ( pair . Key ) ) continue ;
95+ return pair . Value ;
96+ }
97+ }
98+ return AsyncNetworkEngineMap . SingleCloudProvider ;
99+ }
100+
101+ private static void HandleSuccess ( CloudProvider provider , UnityWebRequest rqt , Action < Transmission , TU , GenericErrorResponse > result )
102+ {
103+ if ( rqt . downloadHandler . data == null )
104+ {
105+ Return ( Transmission . ErrorNoData , result ) ;
106+ return ;
107+ }
108+ if ( rqt . downloadHandler . data . Length <= 0 )
109+ {
110+ Return ( Transmission . ErrorNoData , result ) ;
111+ return ;
112+ }
113+
114+ byte [ ] data = rqt . downloadHandler . data ;
115+ if ( provider == CloudProvider . AWS )
116+ {
117+ data = Base64StdEncoding . Decode ( Encoding . ASCII . GetString ( rqt . downloadHandler . data ) ) ;
118+ }
119+
120+ TU packet ;
121+ try
122+ {
123+ packet = _tuParser . ParseFrom ( data ) ;
124+ }
125+ catch
126+ {
127+ packet = default ;
128+ }
129+ Return ( packet != null ? Transmission . Success : Transmission . ErrorParser , packet , default , result ) ;
130+ }
131+
132+ private static void HandleError ( CloudProvider provider , UnityWebRequest rqt , Action < Transmission , TU , GenericErrorResponse > result )
133+ {
134+ if ( rqt . downloadHandler . data == null )
135+ {
136+ Return ( Transmission . ErrorProtocol , result ) ;
137+ return ;
138+ }
139+ if ( rqt . downloadHandler . data . Length <= 0 )
140+ {
141+ Return ( Transmission . ErrorProtocol , result ) ;
142+ return ;
143+ }
144+
145+ byte [ ] data = rqt . downloadHandler . data ;
146+ if ( provider == CloudProvider . AWS )
147+ {
148+ data = Base64StdEncoding . Decode ( Encoding . ASCII . GetString ( rqt . downloadHandler . data ) ) ;
149+ }
150+
151+ var transmission = ( Transmission ) rqt . responseCode ;
152+ GenericErrorResponse packet ;
153+ try
154+ {
155+ packet = _tvParser . ParseFrom ( data ) ;
156+ }
157+ catch
158+ {
159+ packet = default ;
160+ }
161+ Return ( packet != null ? transmission : Transmission . ErrorParser , default , packet , result ) ;
162+ }
163+
164+ private static void Return ( Transmission result , Action < Transmission , TU , GenericErrorResponse > callback )
165+ {
166+ Return ( result , default , default , callback ) ;
167+ }
168+
169+ private static void Return ( Transmission result , TU data , GenericErrorResponse error , Action < Transmission , TU , GenericErrorResponse > callback )
170+ {
171+ if ( callback == null ) return ;
172+ _eventService . QueueAction ( ( ) => callback . Invoke ( result , data , error ) ) ;
173+ //callback.Invoke(result, data, error);
174+ }
175+ }
176+ }
0 commit comments