Skip to content

Commit a8491d8

Browse files
author
mopsicus
committed
feat: default serializer and validator
1 parent 870fcc4 commit a8491d8

File tree

12 files changed

+293
-7
lines changed

12 files changed

+293
-7
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.1.0] - 2024-10-20
6+
7+
### Added
8+
- Default serializer and validator
9+
10+
### Сhanged
11+
- Demo updated
12+
513
## [1.0.0] - 2023-10-10
614

715
### First release of Shardy

Documentation~/welcome.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ If your implementation does not need to do a two-step handshake, you can set "st
4040

4141
Your handshake [validator](./reference.md#-ivalidator) class is passed to the [`Client`](./reference.md#-client) constructor as the first parameter, the next is the serializer.
4242

43+
> [!NOTE]
44+
> You can use the simple built-in `DefaultValidator` validator.
45+
4346
# 🧱 Serializer
4447

4548
Shardy uses a custom serializer for all transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. You have to create your own serializer class by inheriting the [`Serializer`](./reference.md#-iserializer) class, implement encode/decode methods and pass it to your service and client. The main goal – encode [`PayloadData`](./reference.md#payloaddata) to byte array before sending and back after receiving.
@@ -59,6 +62,9 @@ class MyJsonSerializer : ISerializer {
5962
}
6063
```
6164

65+
> [!NOTE]
66+
> You can use the simple built-in `DefaultSerializer` serializer.
67+
6268
I have plans to do some tutorials on the most popular serializers for Unity and their use with Shardy. Stay tuned.
6369

6470
> [!IMPORTANT]

Plugins.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.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class MyHandshake : IValidator {
156156
}
157157
```
158158

159+
> [!NOTE]
160+
> You can use the simple built-in `DefaultValidator` validator.
161+
159162
### Serialization
160163

161164
Shardy supports custom serialization of transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer.
@@ -177,6 +180,9 @@ class MyJsonSerializer : ISerializer {
177180
}
178181
```
179182

183+
> [!NOTE]
184+
> You can use the simple built-in `DefaultSerializer` serializer.
185+
180186
See [documentation](./Documentation~/index.md) for information on all classes and methods.
181187

182188
# 🧩 Modules

README.ru.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class MyHandshake : IValidator {
156156
}
157157
```
158158

159+
> [!NOTE]
160+
> Вы можете использовать простой встроенный валидатор `DefaultValidator`.
161+
159162
### Сериализация
160163

161164
Shardy поддерживает пользовательскую сериализацию передаваемых данных. Вы можете использовать JSON, MessagePack, Protobuf, FlatBuffers и т.д. или свой собственный сериализатор.
@@ -177,6 +180,9 @@ class MyJsonSerializer : ISerializer {
177180
}
178181
```
179182

183+
> [!NOTE]
184+
> Вы можете использовать простой встроенный сериализатор `DefaultSerializer`.
185+
180186
Смотрите [документацию](./Documentation~/index.md) с информацией о всех классах и методах.
181187

182188
# 🧩 Модули

Runtime/Client.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,20 @@ public bool IsConnected {
7373
/// <param name="serializer">Serializer</param>
7474
/// <param name="options">Client options (optional)</param>
7575
/// <param name="handshake">Handshake after connect (optional)</param>
76-
public Client(IValidator validator, ISerializer serializer, ClientOptions options = null, byte[] handshake = null) {
76+
public Client(IValidator validator = null, ISerializer serializer = null, ClientOptions options = null, byte[] handshake = null) {
7777
#if UNITY_WEBGL && !UNITY_EDITOR
7878
WebSocketManager.Init();
7979
#if SHARDY_DEBUG_RAW
8080
WebSocketManager.SetDebug(true);
8181
#endif
8282
#endif
83-
_validator = validator;
84-
_serializer = serializer;
83+
_validator = validator ?? new DefaultValidator();
84+
_serializer = serializer ?? new DefaultSerializer();
8585
_options = options ?? new ClientOptions();
8686
_handshake = handshake;
8787
#if UNITY_WEBGL && !UNITY_EDITOR
8888
if (_options.Type == TransportType.Tcp) {
89-
Logger.Error($"Unable to use TCP transport for WebGL", TAG);
89+
Logger.Error($"unable to use TCP transport for WebGL", TAG);
9090
return;
9191
}
9292
#endif
@@ -231,4 +231,4 @@ public void Destroy() {
231231
_commander.Destroy();
232232
}
233233
}
234-
}
234+
}

Runtime/DefaultSerializer.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Text;
3+
using UnityEngine;
4+
5+
namespace Shardy {
6+
7+
/// <summary>
8+
/// Default serializer
9+
/// </summary>
10+
public class DefaultSerializer : ISerializer {
11+
12+
/// <summary>
13+
/// DTO for serialization
14+
/// </summary>
15+
[Serializable]
16+
class PayloadDTO {
17+
18+
/// <summary>
19+
/// Type of data
20+
/// </summary>
21+
public int Type;
22+
23+
/// <summary>
24+
/// Command or request name
25+
/// </summary>
26+
public string Name;
27+
28+
/// <summary>
29+
/// Request id
30+
/// </summary>
31+
public int Id;
32+
33+
/// <summary>
34+
/// Data
35+
/// </summary>
36+
public string Data;
37+
38+
/// <summary>
39+
/// Error message or code
40+
/// </summary>
41+
public string Error;
42+
}
43+
44+
/// <summary>
45+
/// Serialize data to byte array
46+
/// </summary>
47+
/// <param name="body">Target data</param>
48+
/// <returns>Encoded data</returns>
49+
public byte[] Encode(PayloadData body) {
50+
var dto = new PayloadDTO { Type = (int)body.Type, Name = body.Name, Id = body.Id, Data = body.Data != null ? Convert.ToBase64String(body.Data) : null, Error = body.Error };
51+
var json = JsonUtility.ToJson(dto);
52+
return Encoding.UTF8.GetBytes(Utils.ChangeKeysCase(json, false));
53+
}
54+
55+
/// <summary>
56+
/// Deserialize data
57+
/// </summary>
58+
/// <param name="body">Encoded data</param>
59+
/// <returns>Data to use</returns>
60+
public PayloadData Decode(byte[] body) {
61+
var json = Encoding.UTF8.GetString(body);
62+
var dto = JsonUtility.FromJson<PayloadDTO>(Utils.ChangeKeysCase(json, true));
63+
return new PayloadData((PayloadType)dto.Type, dto.Name, dto.Id, string.IsNullOrEmpty(dto.Data) ? null : Convert.FromBase64String(dto.Data), dto.Error);
64+
}
65+
}
66+
}

Runtime/DefaultSerializer.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.

Runtime/DefaultValidator.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Text;
3+
using UnityEngine;
4+
5+
namespace Shardy {
6+
7+
/// <summary>
8+
/// Default serializer
9+
/// </summary>
10+
public class DefaultValidator : IValidator {
11+
12+
/// <summary>
13+
/// DTO for handshake
14+
/// </summary>
15+
[Serializable]
16+
class HandshakeDTO {
17+
18+
/// <summary>
19+
/// Handshake version
20+
/// </summary>
21+
public int Version;
22+
23+
/// <summary>
24+
/// Timestamp of handshake
25+
/// </summary>
26+
public long Timestamp;
27+
28+
/// <summary>
29+
/// Nonce for handshake
30+
/// </summary>
31+
public string Nonce;
32+
33+
/// <summary>
34+
/// Custom data for handshake
35+
/// </summary>
36+
public string Payload;
37+
}
38+
39+
/// <summary>
40+
/// DTO for acknowledgement
41+
/// </summary>
42+
[Serializable]
43+
class AcknowledgementDTO {
44+
45+
/// <summary>
46+
/// Received flag
47+
/// </summary>
48+
public bool Received;
49+
50+
/// <summary>
51+
/// Nonce for acknowledgement
52+
/// </summary>
53+
public string Nonce;
54+
}
55+
56+
/// <summary>
57+
/// Get handshake data for send
58+
/// </summary>
59+
/// <param name="body">Data for handshake</param>
60+
/// <returns>Data for handshake</returns>
61+
public byte[] Handshake(byte[] body = null) {
62+
var handshake = new HandshakeDTO { Version = 1, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Nonce = Guid.NewGuid().ToString("N"), Payload = body != null ? Encoding.UTF8.GetString(body) : null };
63+
var json = JsonUtility.ToJson(handshake);
64+
return Encoding.UTF8.GetBytes(Utils.ChangeKeysCase(json, false));
65+
}
66+
67+
/// <summary>
68+
/// Get acknowledgement data for send
69+
/// </summary>
70+
/// <param name="body">Data from handshake</param>
71+
/// <returns>Data for acknowledge</returns>
72+
public byte[] Acknowledgement(byte[] body) {
73+
var json = Encoding.UTF8.GetString(body);
74+
var handshake = JsonUtility.FromJson<HandshakeDTO>(Utils.ChangeKeysCase(json, true));
75+
var ack = new AcknowledgementDTO { Received = true, Nonce = handshake.Nonce };
76+
return Encoding.UTF8.GetBytes(Utils.ChangeKeysCase(JsonUtility.ToJson(ack), false));
77+
}
78+
79+
/// <summary>
80+
/// Validate acknowledgement data
81+
/// </summary>
82+
/// <param name="body">Data for validate</param>
83+
/// <returns>Validation result</returns>
84+
public ValidatorState VerifyAcknowledgement(byte[] body) {
85+
var json = Encoding.UTF8.GetString(body);
86+
var ack = JsonUtility.FromJson<AcknowledgementDTO>(Utils.ChangeKeysCase(json, true));
87+
if (!string.IsNullOrEmpty(ack.Nonce)) {
88+
return ValidatorState.Success;
89+
}
90+
return ValidatorState.Failed;
91+
}
92+
}
93+
}

Runtime/DefaultValidator.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.

0 commit comments

Comments
 (0)