RPCClientSocketTransport.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Threading.Tasks;
  3. using InABox.Clients;
  4. using InABox.Core;
  5. using WebSocketSharp;
  6. using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
  7. namespace InABox.Rpc
  8. {
  9. public class RpcClientSocketTransport : RpcClientTransport, IDisposable
  10. {
  11. private WebSocket _socket;
  12. private string _url;
  13. public RpcClientSocketTransport(string url)
  14. {
  15. _url = url;
  16. }
  17. private void Socket_OnOpen(object? sender, EventArgs e)
  18. {
  19. DoOpen();
  20. }
  21. private void Socket_OnMessage(object? sender, MessageEventArgs e)
  22. {
  23. RpcMessage? message = null;
  24. if (e.IsBinary && (e.RawData != null))
  25. message = Serialization.ReadBinary<RpcMessage>(e.RawData, BinarySerializationSettings.Latest);
  26. else if (e.IsText && !string.IsNullOrWhiteSpace(e.Data))
  27. message = Serialization.Deserialize<RpcMessage>(e.Data);
  28. Accept(message);
  29. }
  30. private void Socket_OnClose(object? sender, CloseEventArgs e)
  31. {
  32. DoClose(RpcTransportCloseEventType.Closed);
  33. }
  34. private void Socket_OnError(object? sender, ErrorEventArgs e)
  35. {
  36. DoException(e.Exception);
  37. }
  38. private WebSocket CreateSocket(bool secure)
  39. {
  40. var socket = new WebSocket($"{(secure ? "wss" : "ws")}://{_url}");
  41. // Time to wait before disconnect - the default meant that the client disconnected during debugging, since the ping would fail
  42. socket.WaitTime = TimeSpan.FromSeconds(5);
  43. socket.OnOpen -= Socket_OnOpen;
  44. socket.OnError -= Socket_OnError;
  45. socket.OnClose -= Socket_OnClose;
  46. socket.OnMessage -= Socket_OnMessage;
  47. socket.Connect();
  48. if (socket.ReadyState == WebSocketState.Open)
  49. {
  50. DoOpen();
  51. socket.OnOpen += Socket_OnOpen;
  52. socket.OnError += Socket_OnError;
  53. socket.OnClose += Socket_OnClose;
  54. socket.OnMessage += Socket_OnMessage;
  55. return socket;
  56. }
  57. return null;
  58. }
  59. public override void Connect()
  60. {
  61. var findsocket = new Task<WebSocket>[]
  62. {
  63. Task<WebSocket>.Run(() => CreateSocket(true)),
  64. Task<WebSocket>.Run(() => CreateSocket(false))
  65. } ;
  66. var index = Task.WaitAny(findsocket);
  67. _socket = findsocket[index].Result;
  68. }
  69. public override bool IsConnected() => _socket?.ReadyState == WebSocketState.Open;
  70. public override bool IsSecure() => _socket?.IsSecure == true;
  71. public override void Disconnect()
  72. {
  73. _socket.Close(CloseStatusCode.Normal);
  74. }
  75. public override void Send(RpcMessage message)
  76. {
  77. var buffer = Serialization.WriteBinary(message, BinarySerializationSettings.Latest);
  78. _socket.Send(buffer);
  79. }
  80. protected override RpcClientTransport Clone() => new RpcClientSocketTransport(_url);
  81. public void Dispose()
  82. {
  83. if (IsConnected())
  84. Disconnect();
  85. }
  86. }
  87. }