Merge pull request #103 from onerain88/chore3

Chore3
oneRain 2021-02-02 15:17:07 +08:00 committed by GitHub
commit 57621b5f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 20 deletions

View File

@ -136,9 +136,9 @@ namespace LeanCloud.LiveQuery.Internal {
await client.Close(); await client.Close();
} }
private void OnClientMessage(byte[] bytes) { private void OnClientMessage(byte[] bytes, int length) {
try { try {
string json = Encoding.UTF8.GetString(bytes); string json = Encoding.UTF8.GetString(bytes, 0, length);
Dictionary<string, object> msg = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, Dictionary<string, object> msg = JsonConvert.DeserializeObject<Dictionary<string, object>>(json,
LCJsonConverter.Default); LCJsonConverter.Default);
LCLogger.Debug($"{id} <= {json}"); LCLogger.Debug($"{id} <= {json}");

View File

@ -127,6 +127,6 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.11.4" /> <PackageReference Include="Google.Protobuf" Version="3.14.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -136,7 +136,10 @@ namespace LeanCloud.Realtime {
/// <returns></returns> /// <returns></returns>
public object this[string key] { public object this[string key] {
get { get {
return customProperties[key]; if (customProperties.TryGetValue(key, out object val)) {
return val;
}
return null;
} }
set { set {
customProperties[key] = value; customProperties[key] = value;

View File

@ -160,9 +160,9 @@ namespace LeanCloud.Realtime.Internal.Connection {
} }
} }
private void OnMessage(byte[] bytes) { private void OnMessage(byte[] bytes, int length) {
try { try {
GenericCommand command = GenericCommand.Parser.ParseFrom(bytes); GenericCommand command = GenericCommand.Parser.ParseFrom(bytes, 0, length);
LCLogger.Debug($"{id} <= {FormatCommand(command)}"); LCLogger.Debug($"{id} <= {FormatCommand(command)}");
if (command.HasI) { if (command.HasI) {
// 应答 // 应答

View File

@ -6,13 +6,15 @@ using System.Text;
namespace LeanCloud.Realtime.Internal.WebSocket { namespace LeanCloud.Realtime.Internal.WebSocket {
public class LCWebSocketClient { public class LCWebSocketClient {
// .net standard 2.0 好像在拼合 Frame 时有 bug所以将这个值调整大一些 // .net standard 2.0 好像在拼合 Frame 时有 bug所以将这个值调整大一些
private const int RECV_BUFFER_SIZE = 1024 * 5; private const int SEND_BUFFER_SIZE = 1024 * 5;
private const int RECV_BUFFER_SIZE = 1024 * 8;
private const int MSG_BUFFER_SIZE = 1024 * 10;
private const int CLOSE_TIMEOUT = 5000; private const int CLOSE_TIMEOUT = 5000;
private const int CONNECT_TIMEOUT = 10000; private const int CONNECT_TIMEOUT = 10000;
public Action<byte[]> OnMessage; public Action<byte[], int> OnMessage;
public Action OnClose; public Action OnClose;
@ -23,6 +25,7 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
LCLogger.Debug($"Connecting WebSocket: {server}"); LCLogger.Debug($"Connecting WebSocket: {server}");
Task timeoutTask = Task.Delay(CONNECT_TIMEOUT); Task timeoutTask = Task.Delay(CONNECT_TIMEOUT);
ws = new ClientWebSocket(); ws = new ClientWebSocket();
ws.Options.SetBuffer(RECV_BUFFER_SIZE, SEND_BUFFER_SIZE);
if (!string.IsNullOrEmpty(subProtocol)) { if (!string.IsNullOrEmpty(subProtocol)) {
ws.Options.AddSubProtocol(subProtocol); ws.Options.AddSubProtocol(subProtocol);
} }
@ -78,10 +81,12 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
} }
private async Task StartReceive() { private async Task StartReceive() {
byte[] buffer = new byte[RECV_BUFFER_SIZE]; byte[] recvBuffer = new byte[RECV_BUFFER_SIZE];
byte[] msgBuffer = new byte[MSG_BUFFER_SIZE];
int offset = 0;
try { try {
while (ws.State == WebSocketState.Open) { while (ws.State == WebSocketState.Open) {
WebSocketReceiveResult result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), default); WebSocketReceiveResult result = await ws.ReceiveAsync(new ArraySegment<byte>(recvBuffer), default);
if (result.MessageType == WebSocketMessageType.Close) { if (result.MessageType == WebSocketMessageType.Close) {
LCLogger.Debug($"Receive Closed: {result.CloseStatus}"); LCLogger.Debug($"Receive Closed: {result.CloseStatus}");
if (ws.State == WebSocketState.CloseReceived) { if (ws.State == WebSocketState.CloseReceived) {
@ -98,9 +103,18 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
} else { } else {
// 拼合 WebSocket Message // 拼合 WebSocket Message
int length = result.Count; int length = result.Count;
byte[] data = new byte[length]; if (offset + length > msgBuffer.Length) {
Array.Copy(buffer, data, length); // 反序列化数组大小不够,则以 2x 扩充
OnMessage?.Invoke(data); byte[] newBuffer = new byte[msgBuffer.Length * 2];
Array.Copy(msgBuffer, newBuffer, msgBuffer.Length);
msgBuffer = newBuffer;
}
Array.Copy(recvBuffer, 0, msgBuffer, offset, length);
offset += length;
if (result.EndOfMessage) {
OnMessage?.Invoke(msgBuffer, offset);
offset = 0;
}
} }
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.11.4" /> <PackageReference Include="Google.Protobuf" Version="3.14.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Internal\" /> <Folder Include="Internal\" />

View File

@ -49,7 +49,7 @@ namespace Storage.Test {
Assert.NotNull(current.ObjectId); Assert.NotNull(current.ObjectId);
Assert.IsFalse(current.EmailVerified); Assert.IsFalse(current.EmailVerified);
Assert.IsFalse(current.MobileVerified); Assert.IsFalse(current.MobileVerified);
Assert.AreEqual(current.Mobile, "15101006008"); Assert.AreEqual(current.Mobile, "15101006007");
} }
[Test] [Test]
@ -70,7 +70,7 @@ namespace Storage.Test {
[Test] [Test]
public async Task RelateObject() { public async Task RelateObject() {
LCUser user = await LCUser.LoginByMobilePhoneNumber("15101006007", "112358"); LCUser user = await LCUser.LoginByMobilePhoneNumber("15101006007", "world");
LCObject account = new LCObject("Account"); LCObject account = new LCObject("Account");
account["user"] = user; account["user"] = user;
await account.Save(); await account.Save();

View File

@ -125,7 +125,8 @@ namespace LeanCloud.Storage {
if (key.StartsWith("_")) { if (key.StartsWith("_")) {
throw new ArgumentException("key should not start with '_'"); throw new ArgumentException("key should not start with '_'");
} }
if (key == "objectId" || key == "createdAt" || key == "updatedAt") { if (key == "objectId" || key == "createdAt" || key == "updatedAt" ||
key == "className") {
throw new ArgumentException($"{key} is reserved by LeanCloud"); throw new ArgumentException($"{key} is reserved by LeanCloud");
} }
LCSetOperation setOp = new LCSetOperation(value); LCSetOperation setOp = new LCSetOperation(value);

View File

@ -531,8 +531,8 @@ namespace LeanCloud.Storage {
}; };
try { try {
await Save(); await Save();
oriAuthData.Add(authType, data); oriAuthData[authType] = data;
AuthData = oriAuthData; UpdateAuthData(oriAuthData);
} catch (Exception e) { } catch (Exception e) {
AuthData = oriAuthData; AuthData = oriAuthData;
throw e; throw e;
@ -547,13 +547,19 @@ namespace LeanCloud.Storage {
try { try {
await Save(); await Save();
oriAuthData.Remove(authType); oriAuthData.Remove(authType);
AuthData = oriAuthData; UpdateAuthData(oriAuthData);
} catch (Exception e) { } catch (Exception e) {
AuthData = oriAuthData; AuthData = oriAuthData;
throw e; throw e;
} }
} }
private void UpdateAuthData(Dictionary<string, object> authData) {
LCObjectData objData = new LCObjectData();
objData.CustomPropertyDict["authData"] = authData;
Merge(objData);
}
static async Task<LCUser> Login(Dictionary<string, object> data) { static async Task<LCUser> Login(Dictionary<string, object> data) {
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>("login", data: data); Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>("login", data: data);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);