Skip to content

Commit 6fb7a2f

Browse files
Add back WebGL support + add latest C# SDK features (#107)
* Import TransportLayer logic from C# SDK, and implement Unity-side IHttpClientService * Import EL logic from C# SDK * Bring back WebGL build support * Update JSON pluggable library for Unity * Fix CI scripts for Unity repository * Add missing PNConfiguration in Unity config-asset properties
1 parent 07e221f commit 6fb7a2f

17 files changed

+933
-369
lines changed

.pubnub.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
---
2-
version: v7.2.1
2+
version: v8.0.0
33
changelog:
4+
- date: 2024-12-04
5+
version: v8.0.0
6+
changes:
7+
- type: feature
8+
text: "BREAKING CHANGES: Default Reconnection policy is set to Exponential."
9+
- type: feature
10+
text: "Adding Channel, ChannelGroup, ChannelMetadata and UserMetadata entities to be first-class citizens to access APIs related to them. Currently, access is provided only for subscription APIs."
11+
- type: feature
12+
text: "Default value for EnableEventEngine is set to true, Subscribe operation will be executed by event engine by default."
13+
- type: feature
14+
text: "Added support for CustomMessageType in publish, signal, files features."
15+
- type: feature
16+
text: "Added support for Type field in membership APIs.."
17+
- type: bug
18+
text: "Re-implement WebGL support by implementing a WebGL-targeted Transport Layer utilising UnityWebRequest."
19+
- type: improvement
20+
text: "Removed telemetry manager."
421
- date: 2024-05-09
522
version: v7.2.1
623
changes:
@@ -726,7 +743,7 @@ sdks:
726743
distribution-type: package
727744
distribution-repository: git release
728745
package-name: PubNub.unitypackage
729-
location: https://github.com/pubnub/unity/releases/download/v7.2.1/PubNub.unitypackage
746+
location: https://github.com/pubnub/unity/releases/download/v8.0.0/PubNub.unitypackage
730747
requires:
731748
-
732749
name: "UnityEditor"
@@ -893,7 +910,7 @@ sdks:
893910
distribution-type: package
894911
distribution-repository: git release
895912
package-name: PubNub.unitypackage
896-
location: https://github.com/pubnub/unity/releases/download/v7.2.1/PubNub.unitypackage
913+
location: https://github.com/pubnub/unity/releases/download/v8.0.0/PubNub.unitypackage
897914
requires:
898915
-
899916
name: "UnityEditor"

PubNubUnity/Assets/PubNub/Editor/PNConfigAssetEditor.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ public class PNConfigAssetEditor : Editor {
1515
"SecretKey",
1616
"AuthKey",
1717
"CipherKey",
18-
"EnableTelemetry",
1918
"Secure",
19+
"NonSubscribeRequestTimeout",
20+
"SubscribeTimeout",
21+
"ReconnectionPolicy",
22+
"MaintainPresenceState",
23+
"EnableEventEngine",
24+
"EnableWebGLBuildMode",
25+
"LogToUnityConsole",
2026
"LogVerbosity"
2127
};
2228

Binary file not shown.

PubNubUnity/Assets/PubNub/Runtime/Util/NewtonsoftJsonUnity.cs

Lines changed: 103 additions & 195 deletions
Large diffs are not rendered by default.

PubNubUnity/Assets/PubNub/Runtime/Util/PNConfigAsset.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@ public class PNConfigAsset : ScriptableObject {
1111
public string SecretKey = "";
1212
public string AuthKey;
1313
public string CipherKey;
14-
public bool EnableTelemetry;
1514
public bool Secure;
15+
public int NonSubscribeRequestTimeout = 15;
16+
public int SubscribeTimeout = 310;
17+
public PNReconnectionPolicy ReconnectionPolicy = PNReconnectionPolicy.EXPONENTIAL;
18+
public bool MaintainPresenceState = true;
19+
public bool EnableEventEngine = true;
20+
public bool EnableWebGLBuildMode;
21+
public bool LogToUnityConsole;
1622
public PNLogVerbosity LogVerbosity;
1723

1824
[SerializeField] private bool externalJsonEnabled = false;
@@ -24,16 +30,19 @@ public static implicit operator PNConfiguration(PNConfigAsset asset) {
2430
if (string.IsNullOrEmpty(asset.UserId)) {
2531
throw new NullReferenceException("You need to set the UserId before passing configuration");
2632
}
27-
2833
var config = new PNConfiguration(new UserId(new UserId(asset.UserId)));
2934
config.SubscribeKey = asset.SubscribeKey;
3035
config.PublishKey = asset.PublishKey;
3136
config.SecretKey = asset.SecretKey;
3237
config.AuthKey = asset.AuthKey;
3338
config.CipherKey = asset.CipherKey;
39+
config.NonSubscribeRequestTimeout = asset.NonSubscribeRequestTimeout;
40+
config.SubscribeTimeout = asset.SubscribeTimeout;
41+
config.MaintainPresenceState = asset.MaintainPresenceState;
42+
config.ReconnectionPolicy = asset.ReconnectionPolicy;
43+
config.EnableEventEngine = asset.EnableEventEngine;
3444
config.Secure = asset.Secure;
3545
config.LogVerbosity = asset.LogVerbosity;
36-
config.EnableTelemetry = asset.EnableTelemetry;
3746
return config;
3847
}
3948
}

PubNubUnity/Assets/PubNub/Runtime/Util/PNManagerBehaviour.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ public Pubnub Initialize(string userId) {
3636
}
3737

3838
pnConfiguration.UserId = userId;
39-
pubnub = new Pubnub(pnConfiguration);
40-
pubnub.SetJsonPluggableLibrary(new NewtonsoftJsonUnity(pnConfiguration, ((PNConfiguration)pnConfiguration).PubnubLog));
39+
var pnConfig = ((PNConfiguration)pnConfiguration);
40+
if (pnConfiguration.LogToUnityConsole) {
41+
pnConfig.PubnubLog = new UnityPNLog();
42+
}
43+
pubnub = pnConfiguration.EnableWebGLBuildMode ? new Pubnub(pnConfig, new UnityWebGLHttpClientService()) : new Pubnub(pnConfig);
44+
pubnub.SetJsonPluggableLibrary(new NewtonsoftJsonUnity(pnConfig, pnConfig.PubnubLog));
4145
pubnub.AddListener(listener);
4246
return pubnub;
43-
4447
}
4548

4649
protected virtual void OnDestroy() {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using PubnubApi;
2+
using UnityEngine;
3+
4+
public class UnityPNLog : IPubnubLog
5+
{
6+
public void WriteToLog(string logText) {
7+
Debug.Log(logText);
8+
}
9+
}

PubNubUnity/Assets/PubNub/Runtime/Util/UnityPNLog.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using UnityEngine;
6+
using UnityEngine.Networking;
7+
8+
namespace PubnubApi.Unity {
9+
10+
/// <summary>
11+
/// This is an implementation of the PubNub Transport Layer created for Web GL builds compatibility
12+
/// </summary>
13+
public class UnityWebGLHttpClientService : IHttpClientService {
14+
private TransportResponse UnityRequestToResponse(UnityWebRequest request) {
15+
return new TransportResponse() {
16+
StatusCode = (int)request.responseCode,
17+
Content = request.downloadHandler?.data,
18+
RequestUrl = request.url,
19+
Headers = request.GetResponseHeaders()
20+
.ToDictionary(
21+
x => x.Key,
22+
y => (IEnumerable<string>)new[] { y.Value })
23+
};
24+
}
25+
26+
private void PrepareUnityRequest(UnityWebRequest request, TransportRequest transportRequest) {
27+
if (transportRequest.Timeout.HasValue) {
28+
request.timeout = (int)transportRequest.Timeout.Value.TotalSeconds;
29+
}
30+
31+
if (transportRequest.Headers.Keys.Count > 0) {
32+
foreach (var kvp in transportRequest.Headers) {
33+
request.SetRequestHeader(kvp.Key, kvp.Value);
34+
}
35+
}
36+
}
37+
38+
public async Task<TransportResponse> DeleteRequest(TransportRequest transportRequest) {
39+
TransportResponse response;
40+
try {
41+
var deleteRequest = UnityWebRequest.Delete(transportRequest.RequestUrl);
42+
PrepareUnityRequest(deleteRequest, transportRequest);
43+
var taskCompletionSource = new TaskCompletionSource<TransportResponse>();
44+
transportRequest.CancellationToken.Register(() => {
45+
deleteRequest.Abort();
46+
taskCompletionSource.TrySetCanceled();
47+
});
48+
deleteRequest.SendWebRequest().completed += _ => {
49+
taskCompletionSource.TrySetResult(UnityRequestToResponse(deleteRequest));
50+
};
51+
response = await taskCompletionSource.Task.ConfigureAwait(false);
52+
} catch (Exception ex) {
53+
Debug.LogError($"DELETE Error: {ex}");
54+
response = new TransportResponse() {
55+
RequestUrl = transportRequest.RequestUrl,
56+
Error = ex
57+
};
58+
}
59+
return response;
60+
}
61+
62+
public async Task<TransportResponse> GetRequest(TransportRequest transportRequest) {
63+
TransportResponse response;
64+
try {
65+
var getRequest = UnityWebRequest.Get(transportRequest.RequestUrl);
66+
PrepareUnityRequest(getRequest, transportRequest);
67+
var taskCompletionSource = new TaskCompletionSource<TransportResponse>();
68+
transportRequest.CancellationToken.Register(() => {
69+
getRequest.Abort();
70+
taskCompletionSource.TrySetCanceled();
71+
});
72+
getRequest.SendWebRequest().completed += _ => {
73+
taskCompletionSource.TrySetResult(UnityRequestToResponse(getRequest));
74+
};
75+
response = await taskCompletionSource.Task.ConfigureAwait(false);
76+
} catch (Exception ex) {
77+
Debug.LogError($"GET Error: {ex}");
78+
response = new TransportResponse() {
79+
RequestUrl = transportRequest.RequestUrl,
80+
Error = ex
81+
};
82+
}
83+
return response;
84+
}
85+
86+
public async Task<TransportResponse> PostRequest(TransportRequest transportRequest) {
87+
TransportResponse response;
88+
try {
89+
var formData = new List<IMultipartFormSection>();
90+
if (!string.IsNullOrEmpty(transportRequest.BodyContentString)) {
91+
formData.Add(new MultipartFormDataSection(transportRequest.BodyContentString));
92+
} else if (transportRequest.BodyContentBytes != null) {
93+
formData.Add(new MultipartFormDataSection(transportRequest.BodyContentBytes));
94+
}
95+
96+
var postRequest = UnityWebRequest.Post(transportRequest.RequestUrl, formData);
97+
PrepareUnityRequest(postRequest, transportRequest);
98+
var taskCompletionSource = new TaskCompletionSource<TransportResponse>();
99+
transportRequest.CancellationToken.Register(() => {
100+
postRequest.Abort();
101+
taskCompletionSource.TrySetCanceled();
102+
});
103+
postRequest.SendWebRequest().completed += _ => {
104+
taskCompletionSource.TrySetResult(UnityRequestToResponse(postRequest));
105+
};
106+
response = await taskCompletionSource.Task.ConfigureAwait(false);
107+
} catch (Exception ex) {
108+
Debug.LogError($"POST Error: {ex}");
109+
response = new TransportResponse() {
110+
RequestUrl = transportRequest.RequestUrl,
111+
Error = ex
112+
};
113+
}
114+
return response;
115+
}
116+
117+
public async Task<TransportResponse> PatchRequest(TransportRequest transportRequest) {
118+
TransportResponse response;
119+
try {
120+
UnityWebRequest patchRequest;
121+
if (!string.IsNullOrEmpty(transportRequest.BodyContentString)) {
122+
patchRequest = UnityWebRequest.Put(transportRequest.RequestUrl, transportRequest.BodyContentString);
123+
} else if (transportRequest.BodyContentBytes != null) {
124+
patchRequest = UnityWebRequest.Put(transportRequest.RequestUrl, transportRequest.BodyContentBytes);
125+
} else {
126+
throw new ArgumentException("PATCH Transport Request has no body!");
127+
}
128+
patchRequest.method = "PATCH";
129+
130+
PrepareUnityRequest(patchRequest, transportRequest);
131+
var taskCompletionSource = new TaskCompletionSource<TransportResponse>();
132+
transportRequest.CancellationToken.Register(() => {
133+
patchRequest.Abort();
134+
taskCompletionSource.TrySetCanceled();
135+
});
136+
patchRequest.SendWebRequest().completed += _ => {
137+
taskCompletionSource.TrySetResult(UnityRequestToResponse(patchRequest));
138+
};
139+
response = await taskCompletionSource.Task.ConfigureAwait(false);
140+
} catch (Exception ex) {
141+
Debug.LogError($"PATCH Error: {ex}");
142+
response = new TransportResponse() {
143+
RequestUrl = transportRequest.RequestUrl,
144+
Error = ex
145+
};
146+
}
147+
148+
return response;
149+
}
150+
151+
public async Task<TransportResponse> PutRequest(TransportRequest transportRequest) {
152+
TransportResponse response;
153+
try {
154+
UnityWebRequest putRequest;
155+
if (!string.IsNullOrEmpty(transportRequest.BodyContentString)) {
156+
putRequest = UnityWebRequest.Put(transportRequest.RequestUrl, transportRequest.BodyContentString);
157+
} else if (transportRequest.BodyContentBytes != null) {
158+
putRequest = UnityWebRequest.Put(transportRequest.RequestUrl, transportRequest.BodyContentBytes);
159+
} else {
160+
throw new ArgumentException("PUT Transport Request has no body!");
161+
}
162+
163+
PrepareUnityRequest(putRequest, transportRequest);
164+
var taskCompletionSource = new TaskCompletionSource<TransportResponse>();
165+
transportRequest.CancellationToken.Register(() => {
166+
putRequest.Abort();
167+
taskCompletionSource.TrySetCanceled();
168+
});
169+
putRequest.SendWebRequest().completed += _ => {
170+
taskCompletionSource.TrySetResult(UnityRequestToResponse(putRequest));
171+
};
172+
response = await taskCompletionSource.Task.ConfigureAwait(false);
173+
} catch (Exception ex) {
174+
Debug.LogError($"PUT Error: {ex}");
175+
response = new TransportResponse() {
176+
RequestUrl = transportRequest.RequestUrl,
177+
Error = ex
178+
};
179+
}
180+
181+
return response;
182+
}
183+
}
184+
}

PubNubUnity/Assets/PubNub/Runtime/Util/UnityWebGLHttpClientService.cs.meta

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

PubNubUnity/Assets/PubNub/Samples/DemoKeys.asset

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ MonoBehaviour:
1414
m_EditorClassIdentifier:
1515
PublishKey: demo
1616
SubscribeKey: demo
17+
SecretKey:
1718
AuthKey:
1819
CipherKey:
19-
EnableTelemetry: 0
2020
Secure: 0
21-
LogVerbosity: 1
21+
EnableEventEngine: 0
22+
EnableWebGLBuildMode: 0
23+
LogToUnityConsole: 0
24+
LogVerbosity: 0
2225
externalJsonEnabled: 1
2326
externalJsonFile: {fileID: 4900000, guid: cece9ff28bff4146b7592375b7909cc0, type: 3}

PubNubUnity/Assets/PubNub/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.pubnub.sdk",
3-
"version": "7.2.1",
3+
"version": "8.0.0",
44
"displayName": "PubNub SDK",
55
"description": "PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks",
66
"unity": "2021.3",

PubNubUnity/Packages/packages-lock.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@
9191
"source": "registry",
9292
"dependencies": {
9393
"com.unity.ugui": "1.0.0",
94-
"com.unity.modules.unityanalytics": "1.0.0",
95-
"com.unity.modules.unitywebrequest": "1.0.0",
96-
"com.unity.modules.jsonserialize": "1.0.0",
97-
"com.unity.modules.androidjni": "1.0.0",
9894
"com.unity.services.core": "1.3.1",
99-
"com.unity.services.analytics": "4.0.1"
95+
"com.unity.modules.androidjni": "1.0.0",
96+
"com.unity.services.analytics": "4.0.1",
97+
"com.unity.modules.jsonserialize": "1.0.0",
98+
"com.unity.modules.unityanalytics": "1.0.0",
99+
"com.unity.modules.unitywebrequest": "1.0.0"
100100
},
101101
"url": "https://packages.unity.com"
102102
},
@@ -115,9 +115,9 @@
115115
"depth": 1,
116116
"source": "registry",
117117
"dependencies": {
118-
"com.unity.modules.unitywebrequest": "1.0.0",
118+
"com.unity.modules.androidjni": "1.0.0",
119119
"com.unity.nuget.newtonsoft-json": "3.0.2",
120-
"com.unity.modules.androidjni": "1.0.0"
120+
"com.unity.modules.unitywebrequest": "1.0.0"
121121
},
122122
"url": "https://packages.unity.com"
123123
},
@@ -162,9 +162,9 @@
162162
"depth": 0,
163163
"source": "registry",
164164
"dependencies": {
165+
"com.unity.modules.audio": "1.0.0",
165166
"com.unity.modules.director": "1.0.0",
166167
"com.unity.modules.animation": "1.0.0",
167-
"com.unity.modules.audio": "1.0.0",
168168
"com.unity.modules.particlesystem": "1.0.0"
169169
},
170170
"url": "https://packages.unity.com"

0 commit comments

Comments
 (0)