Skip to content

Commit c06f4d7

Browse files
committed
Update package.json
0 parents  commit c06f4d7

17 files changed

+1145
-0
lines changed

.icon.png

6.3 KB
Loading

LICENSE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
MIT License
2+
3+
Copyright (c) 2015, Unity Technologies
4+
5+
Copyright (c) 2020 Game Workstore
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.

LICENSE.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Async Network Engine
2+
3+
Application Http requests made easy to interoperability with Go Lang Backend + Google Protobuf functions!
4+
5+
Supported Cloud Functions:
6+
- Google Cloud Functions
7+
- Amazon Web Services Lambdas
8+
9+
Use at your own risk!
10+
11+
# CppSDK
12+
13+
Visit this repo for more info: https://github.com/GameWorkstore/async-network-engine-cpp
14+
15+
# GoLangSDK
16+
17+
Visit this repo for more info: https://github.com/GameWorkstore/async-network-engine-go
18+
19+
# UnitySDK
20+
21+
## How to install
22+
23+
At package.json, add these 3 lines of code:
24+
```json
25+
"com.gameworkstore.asyncnetworkengine": "git://github.com/GameWorkstore/async-network-engine.git#0.2.1",
26+
"com.gameworkstore.googleprotobufunity": "git://github.com/GameWorkstore/google-protobuf-unity.git#3.15.2006",
27+
"com.gameworkstore.patterns": "git://github.com/GameWorkstore/patterns.git#1.1.2"
28+
```
29+
30+
And wait for unity to download and compile the package.
31+
32+
or update package for a newer version, update end of line from 0.2.1 to any released version on Releases.
33+
34+
## Usage Examples
35+
36+
You can find usage examples on Assets/Tests/ folder, for each cloud.
37+
38+
# FAQ
39+
40+
## Uploading to Google Cloud Functions
41+
42+
on upmsync, the job 'upload_gcp' illustrates a possible way to upload your functions into GCP.
43+
Requires a service account to enable it to upload.
44+
45+
### Uploading to Amazon Web Services
46+
47+
on upmsync.yaml, the job 'upload_aws' illustrates a possible way to upload your functions into AWS.
48+
Requires a service account to enable it to upload.
49+
> You need to set the template 'cloudformation_function.yaml' public in your bucket repository to enable AWS::Stack to read from it.
50+
51+
## GCP Troubleshoot
52+
53+
> My function is returning ErrorProtocol for any input.
54+
if you don't give access public for your function it might fail
55+
56+
## AWS Troubleshoot
57+
> CloudFormation is returning errors
58+
59+
Verify all variables, !Ref and links, you might be forgetting something. CloudFormations is very sensitive to linkage errors.
60+
61+
> My lambda is returning error 500 Internal Server error.
62+
63+
If you are receiving this and error object is returning null, it might be a bad configuration causing your lambda to not run.
64+
Verify if you function is running by adding a fmt.Println("test") at main() function to ensure the function is starting.
65+
Some issues that may prevent the start of function:
66+
- The functions ins't at correct path when extracted from the zip.
67+
- The function package name isn't main where main() function is declared.
68+
- lambda.Start() is never begin called to initialize the function.
69+
- The function is crashing upon initialization
70+
71+
If the function is working normally, them you might receive error 500 - ErrorInternalServer with AWSError, when specified by the programmer.
72+
73+
# Contributions
74+
75+
If you are using this library and want to submit a change, go ahead! Overall, this project accepts contributions if:
76+
- Is a bug fix;
77+
- Or, is a generalization of a well-known issue;
78+
- Or is performance improvement;
79+
- Or is an improvement to already supported feature.
80+
81+
Also, you can donate to allow us to drink coffee while we improve it for you!

README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/AsyncNetworkEngine.cs

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
using Google.Protobuf;
2+
using System;
3+
using System.Collections;
4+
using System.Text;
5+
using UnityEngine.Networking;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
9+
namespace GameWorkstore.AsyncNetworkEngine
10+
{
11+
public enum CloudProvider
12+
{
13+
Gcp = 0,
14+
Aws = 1
15+
}
16+
17+
public class FileData
18+
{
19+
public string URL;
20+
public byte[] Data;
21+
}
22+
23+
public static class AsyncNetworkEngineMap
24+
{
25+
internal static bool IsSingleCloud = true;
26+
internal static CloudProvider SingleCloudProvider = CloudProvider.Aws;
27+
internal static Dictionary<string, CloudProvider> MapCloudProvider;
28+
29+
/// <summary>
30+
/// Setup a single cloud provider for all functions.
31+
/// </summary>
32+
/// <param name="cloudProvider">Target cloud provider implementation.</param>
33+
public static void SetupCloud(CloudProvider cloudProvider)
34+
{
35+
IsSingleCloud = true;
36+
SingleCloudProvider = cloudProvider;
37+
}
38+
39+
/// <summary>
40+
/// Setup a multi cloud provider for all functions.
41+
/// </summary>
42+
/// <param name="mapCloudProvider">Maps base url to cloud provider. Use the lowest possible string to differentiate clouds.</param>
43+
public static void SetupCloudMap(Dictionary<string, CloudProvider> mapCloudProvider)
44+
{
45+
IsSingleCloud = false;
46+
MapCloudProvider = mapCloudProvider;
47+
}
48+
}
49+
50+
public static class AsyncNetworkEngine
51+
{
52+
private static Patterns.EventService _eventService;
53+
54+
public static void Download(string url,Action<Transmission,FileData> callback)
55+
{
56+
if (_eventService == null) _eventService = Patterns.ServiceProvider.GetService<Patterns.EventService>();
57+
_eventService.StartCoroutine(SendRequest(new[] { url }, (result,files) => {
58+
callback?.Invoke(result,files.FirstOrDefault());
59+
}));
60+
}
61+
62+
public static void Download(string[] urls, Action<Transmission, Patterns.HighSpeedArray<FileData>> callback)
63+
{
64+
if (_eventService == null) _eventService = Patterns.ServiceProvider.GetService<Patterns.EventService>();
65+
_eventService.StartCoroutine(SendRequest(urls, callback));
66+
}
67+
68+
public static IEnumerator SendRequest(string[] urls, Action<Transmission, Patterns.HighSpeedArray<FileData>> callback)
69+
{
70+
var data = new Patterns.HighSpeedArray<FileData>(urls.Length);
71+
foreach(var url in urls)
72+
{
73+
using (var rqt = UnityWebRequest.Get(url))
74+
{
75+
yield return rqt.SendWebRequest();
76+
77+
switch (rqt.result)
78+
{
79+
case UnityWebRequest.Result.ConnectionError:
80+
Return(Transmission.ErrorConnection, data, callback);
81+
break;
82+
case UnityWebRequest.Result.ProtocolError:
83+
Return(Transmission.ErrorProtocol, data, callback);
84+
break;
85+
case UnityWebRequest.Result.DataProcessingError:
86+
Return(Transmission.ErrorDecode, data, callback);
87+
break;
88+
case UnityWebRequest.Result.Success:
89+
data.Add(new FileData()
90+
{
91+
URL = url,
92+
Data = rqt.downloadHandler.data
93+
});
94+
break;
95+
}
96+
}
97+
}
98+
Return(Transmission.Success, data, callback);
99+
}
100+
101+
private static void Return(Transmission result, Patterns.HighSpeedArray<FileData> data, Action<Transmission, Patterns.HighSpeedArray<FileData>> callback)
102+
{
103+
if (_eventService != null)
104+
{
105+
_eventService.QueueAction(() => callback.Invoke(result, data));
106+
}
107+
else
108+
{
109+
callback?.Invoke(result, data);
110+
}
111+
}
112+
}
113+
114+
/// <summary>
115+
/// Implements a UnityRequest for google protobuf web functions.
116+
/// </summary>
117+
/// <typeparam name="TRqt">Request</typeparam>
118+
/// <typeparam name="TResp">Response</typeparam>
119+
public static class AsyncNetworkEngine<TRqt,TResp>
120+
where TRqt : IMessage<TRqt>, new()
121+
where TResp : IMessage<TResp>, new()
122+
{
123+
private static readonly MessageParser<TResp> _tuParser = new MessageParser<TResp>(() => new TResp());
124+
private static readonly MessageParser<GenericErrorResponse> _tvParser = new MessageParser<GenericErrorResponse>(() => new GenericErrorResponse());
125+
private static Patterns.EventService _eventService;
126+
127+
public static void Send(string url, TRqt request, Action<Transmission, TResp, GenericErrorResponse> callback)
128+
{
129+
if (_eventService == null) _eventService = Patterns.ServiceProvider.GetService<Patterns.EventService>();
130+
_eventService.StartCoroutine(SendRequest(url, request, callback));
131+
}
132+
133+
public static IEnumerator SendRequest(string url, TRqt request, Action<Transmission, TResp, GenericErrorResponse> callback)
134+
{
135+
//Notice: APIGateway automatically converts binary data into base64 strings
136+
using (var rqt = new UnityWebRequest(url, "POST")
137+
{
138+
uploadHandler = new UploadHandlerRaw(request.ToByteArray()),
139+
downloadHandler = new DownloadHandlerBuffer()
140+
})
141+
{
142+
yield return rqt.SendWebRequest();
143+
144+
switch (rqt.result)
145+
{
146+
case UnityWebRequest.Result.ConnectionError:
147+
Return(Transmission.ErrorConnection, callback);
148+
break;
149+
case UnityWebRequest.Result.ProtocolError:
150+
HandleError(GetCloudProvider(ref url), rqt, callback);
151+
break;
152+
case UnityWebRequest.Result.Success:
153+
while (!rqt.downloadHandler.isDone) yield return null;
154+
HandleSuccess(GetCloudProvider(ref url), rqt, callback);
155+
break;
156+
}
157+
}
158+
}
159+
160+
private static CloudProvider GetCloudProvider(ref string url)
161+
{
162+
if (!AsyncNetworkEngineMap.IsSingleCloud)
163+
{
164+
foreach (var pair in AsyncNetworkEngineMap.MapCloudProvider)
165+
{
166+
if (!url.StartsWith(pair.Key)) continue;
167+
return pair.Value;
168+
}
169+
}
170+
return AsyncNetworkEngineMap.SingleCloudProvider;
171+
}
172+
173+
private static void HandleSuccess(CloudProvider provider, UnityWebRequest rqt, Action<Transmission, TResp, GenericErrorResponse> callback)
174+
{
175+
if (rqt.downloadHandler.data == null)
176+
{
177+
Return(Transmission.ErrorNoData, callback);
178+
return;
179+
}
180+
181+
var data = rqt.downloadHandler.data;
182+
if (provider == CloudProvider.Aws)
183+
{
184+
var s = Encoding.ASCII.GetString(rqt.downloadHandler.data);
185+
if (!Base64StdEncoding.Decode(s, out data))
186+
{
187+
Return(Transmission.ErrorParser, default, new GenericErrorResponse(){ Error = "base64 string is invalid:" + s }, callback);
188+
return;
189+
}
190+
}
191+
192+
TResp packet;
193+
try
194+
{
195+
packet = _tuParser.ParseFrom(data);
196+
}
197+
catch
198+
{
199+
Return(Transmission.ErrorParser, callback);
200+
return;
201+
}
202+
Return(Transmission.Success, packet, default, callback);
203+
}
204+
205+
private static void HandleError(CloudProvider provider, UnityWebRequest rqt, Action<Transmission, TResp, GenericErrorResponse> callback)
206+
{
207+
if (rqt.downloadHandler.data == null)
208+
{
209+
Return(Transmission.ErrorProtocol, callback);
210+
return;
211+
}
212+
213+
var data = rqt.downloadHandler.data;
214+
if (provider == CloudProvider.Aws)
215+
{
216+
var s = Encoding.ASCII.GetString(rqt.downloadHandler.data);
217+
if (!Base64StdEncoding.Decode(s, out data))
218+
{
219+
Return(Transmission.ErrorParser, default, new GenericErrorResponse(){ Error = "base64 string is invalid:" + s }, callback);
220+
return;
221+
}
222+
}
223+
224+
var transmission = (Transmission)rqt.responseCode;
225+
GenericErrorResponse packet;
226+
try
227+
{
228+
packet = _tvParser.ParseFrom(data);
229+
}
230+
catch
231+
{
232+
Return(Transmission.ErrorParser, callback);
233+
return;
234+
}
235+
Return(transmission, default, packet, callback);
236+
}
237+
238+
private static void Return(Transmission result, Action<Transmission, TResp, GenericErrorResponse> callback)
239+
{
240+
Return(result, default, default, callback);
241+
}
242+
243+
private static void Return(Transmission result, TResp data, GenericErrorResponse error, Action<Transmission, TResp, GenericErrorResponse> callback)
244+
{
245+
if (callback == null) return;
246+
if(_eventService != null)
247+
{
248+
_eventService.QueueAction(() => callback.Invoke(result, data, error));
249+
}
250+
else
251+
{
252+
callback.Invoke(result, data, error);
253+
}
254+
}
255+
}
256+
}

0 commit comments

Comments
 (0)