|
@@ -1,4 +1,7 @@
|
|
|
using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using InABox.Clients;
|
|
|
using InABox.Core;
|
|
@@ -9,11 +12,13 @@ namespace InABox.Rpc
|
|
|
{
|
|
|
public class RpcClientSocketTransport : RpcClientTransport, IDisposable
|
|
|
{
|
|
|
- private WebSocket _socket;
|
|
|
- private string _url;
|
|
|
- public RpcClientSocketTransport(string url)
|
|
|
+ private WebSocket? _socket;
|
|
|
+
|
|
|
+ private string[] _urls;
|
|
|
+
|
|
|
+ public RpcClientSocketTransport(string[] urls)
|
|
|
{
|
|
|
- _url = url;
|
|
|
+ _urls = urls;
|
|
|
}
|
|
|
|
|
|
private void Socket_OnOpen(object? sender, EventArgs e)
|
|
@@ -43,12 +48,13 @@ namespace InABox.Rpc
|
|
|
}
|
|
|
|
|
|
|
|
|
- private WebSocket CreateSocket(bool secure)
|
|
|
+ private WebSocket? CreateSocket(string url, bool secure)
|
|
|
{
|
|
|
- var socket = new WebSocket($"{(secure ? "wss" : "ws")}://{_url}");
|
|
|
+ var address = $"{(secure ? "wss" : "ws")}://{url}";
|
|
|
+ var socket = new WebSocket(address);
|
|
|
|
|
|
// Time to wait before disconnect - the default meant that the client disconnected during debugging, since the ping would fail
|
|
|
- socket.WaitTime = TimeSpan.FromSeconds(5);
|
|
|
+ socket.WaitTime = TimeSpan.FromSeconds(60);
|
|
|
socket.OnOpen -= Socket_OnOpen;
|
|
|
socket.OnError -= Socket_OnError;
|
|
|
socket.OnClose -= Socket_OnClose;
|
|
@@ -65,20 +71,28 @@ namespace InABox.Rpc
|
|
|
|
|
|
return socket;
|
|
|
}
|
|
|
-
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public override void Connect()
|
|
|
{
|
|
|
- var findsocket = new Task<WebSocket>[]
|
|
|
+ List<Task<WebSocket>> tasks = new List<Task<WebSocket>>();
|
|
|
+ foreach (var url in _urls)
|
|
|
{
|
|
|
- Task<WebSocket>.Run(() => CreateSocket(true)),
|
|
|
- Task<WebSocket>.Run(() => CreateSocket(false))
|
|
|
- } ;
|
|
|
- var index = Task.WaitAny(findsocket);
|
|
|
-
|
|
|
- _socket = findsocket[index].Result;
|
|
|
+ tasks.Add(Task<WebSocket>.Run(() => CreateSocket(url, true)));
|
|
|
+ tasks.Add(Task<WebSocket>.Run(() => CreateSocket(url, false)));
|
|
|
+ }
|
|
|
+ while (tasks.Count > 0)
|
|
|
+ {
|
|
|
+ var result = Task.WhenAny(tasks).Result;
|
|
|
+ if (result.Result == null)
|
|
|
+ tasks.Remove(result);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _socket = result.Result;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public override bool IsConnected() => _socket?.ReadyState == WebSocketState.Open;
|
|
@@ -86,16 +100,16 @@ namespace InABox.Rpc
|
|
|
|
|
|
public override void Disconnect()
|
|
|
{
|
|
|
- _socket.Close(CloseStatusCode.Normal);
|
|
|
+ _socket?.Close(CloseStatusCode.Normal);
|
|
|
}
|
|
|
|
|
|
public override void Send(RpcMessage message)
|
|
|
{
|
|
|
- var buffer = Serialization.WriteBinary(message, BinarySerializationSettings.Latest);
|
|
|
- _socket.Send(buffer);
|
|
|
+ var buffer = message.WriteBinary(BinarySerializationSettings.Latest);
|
|
|
+ _socket?.Send(buffer);
|
|
|
}
|
|
|
|
|
|
- protected override RpcClientTransport Clone() => new RpcClientSocketTransport(_url);
|
|
|
+ protected override RpcClientTransport Clone() => new RpcClientSocketTransport(_urls);
|
|
|
|
|
|
public void Dispose()
|
|
|
{
|