RPCClientSocketTransport.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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.Connect();
  44. if (socket.ReadyState == WebSocketState.Open)
  45. {
  46. DoOpen();
  47. socket.OnOpen += Socket_OnOpen;
  48. socket.OnError += Socket_OnError;
  49. socket.OnClose += Socket_OnClose;
  50. socket.OnMessage += Socket_OnMessage;
  51. return socket;
  52. }
  53. return null;
  54. }
  55. public override void Connect()
  56. {
  57. var findsocket = new Task<WebSocket>[]
  58. {
  59. Task<WebSocket>.Run(() => CreateSocket(true)),
  60. Task<WebSocket>.Run(() => CreateSocket(false))
  61. } ;
  62. var index = Task.WaitAny(findsocket);
  63. _socket = findsocket[index].Result;
  64. }
  65. public override bool IsConnected() => _socket?.ReadyState == WebSocketState.Open;
  66. public override bool IsSecure() => _socket?.IsSecure == true;
  67. public override void Disconnect()
  68. {
  69. _socket.Close(CloseStatusCode.Normal);
  70. }
  71. public override void Send(RpcMessage message)
  72. {
  73. var buffer = Serialization.WriteBinary(message, BinarySerializationSettings.Latest);
  74. _socket.Send(buffer);
  75. }
  76. protected override RpcClientTransport Clone() => new RpcClientSocketTransport(_url);
  77. public void Dispose()
  78. {
  79. if (IsConnected())
  80. Disconnect();
  81. }
  82. }
  83. }