123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #if !BESTHTTP_DISABLE_SIGNALR
- #if !BESTHTTP_DISABLE_WEBSOCKET
- using System;
- using System.Text;
- using BestHTTP;
- using BestHTTP.JSON;
- using BestHTTP.SignalR.Hubs;
- using BestHTTP.SignalR.Messages;
- using BestHTTP.SignalR.JsonEncoders;
- namespace BestHTTP.SignalR.Transports
- {
- public sealed class WebSocketTransport : TransportBase
- {
- #region Overridden Properties
- public override bool SupportsKeepAlive { get { return true; } }
- public override TransportTypes Type { get { return TransportTypes.WebSocket; } }
- #endregion
- private WebSocket.WebSocket wSocket;
- public WebSocketTransport(Connection connection)
- : base("webSockets", connection)
- {
- }
- #region Overrides from TransportBase
- /// <summary>
- /// Websocket transport specific connection logic. It will create a WebSocket instance, and starts to connect to the server.
- /// </summary>
- public override void Connect()
- {
- if (wSocket != null)
- {
- HTTPManager.Logger.Warning("WebSocketTransport", "Start - WebSocket already created!");
- return;
- }
- // Skip the Connecting state if we are reconnecting. If the connect succeeds, we will set the Started state directly
- if (this.State != TransportStates.Reconnecting)
- this.State = TransportStates.Connecting;
- RequestTypes requestType = this.State == TransportStates.Reconnecting ? RequestTypes.Reconnect : RequestTypes.Connect;
- Uri uri = Connection.BuildUri(requestType, this);
- // Create the WebSocket instance
- wSocket = new WebSocket.WebSocket(uri);
- // Set up eventhandlers
- wSocket.OnOpen += WSocket_OnOpen;
- wSocket.OnMessage += WSocket_OnMessage;
- wSocket.OnClosed += WSocket_OnClosed;
- wSocket.OnErrorDesc += WSocket_OnError;
- #if !UNITY_WEBGL || UNITY_EDITOR
- // prepare the internal http request
- Connection.PrepareRequest(wSocket.InternalRequest, requestType);
- #endif
- // start opening the websocket protocol
- wSocket.Open();
- }
- protected override void SendImpl(string json)
- {
- if (wSocket != null && wSocket.IsOpen)
- wSocket.Send(json);
- }
- public override void Stop()
- {
- if (wSocket != null)
- {
- wSocket.OnOpen = null;
- wSocket.OnMessage = null;
- wSocket.OnClosed = null;
- wSocket.OnErrorDesc = null;
- wSocket.Close();
- wSocket = null;
- }
- }
- protected override void Started()
- {
- // Nothing to be done here for this transport
- }
- /// <summary>
- /// The /abort request successfully finished
- /// </summary>
- protected override void Aborted()
- {
- // if the websocket is still open, close it
- if (wSocket != null && wSocket.IsOpen)
- {
- wSocket.Close();
- wSocket = null;
- }
- }
- #endregion
- #region WebSocket Events
- void WSocket_OnOpen(WebSocket.WebSocket webSocket)
- {
- if (webSocket != wSocket)
- return;
- HTTPManager.Logger.Information("WebSocketTransport", "WSocket_OnOpen");
- OnConnected();
- }
- void WSocket_OnMessage(WebSocket.WebSocket webSocket, string message)
- {
- if (webSocket != wSocket)
- return;
- IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, message);
- if (msg != null)
- Connection.OnMessage(msg);
- }
- void WSocket_OnClosed(WebSocket.WebSocket webSocket, ushort code, string message)
- {
- if (webSocket != wSocket)
- return;
- string reason = code.ToString() + " : " + message;
- HTTPManager.Logger.Information("WebSocketTransport", "WSocket_OnClosed " + reason);
- if (this.State == TransportStates.Closing)
- this.State = TransportStates.Closed;
- else
- Connection.Error(reason);
- }
- void WSocket_OnError(WebSocket.WebSocket webSocket, string reason)
- {
- if (webSocket != wSocket)
- return;
- // On WP8.1, somehow we receive an exception that the remote server forcibly closed the connection instead of the
- // WebSocket closed packet... Also, even the /abort request didn't finished.
- if (this.State == TransportStates.Closing ||
- this.State == TransportStates.Closed)
- {
- base.AbortFinished();
- }
- else
- {
- HTTPManager.Logger.Error("WebSocketTransport", "WSocket_OnError " + reason);
- this.State = TransportStates.Closed;
- Connection.Error(reason);
- }
- }
- #endregion
- }
- }
- #endif
- #endif
|