Exemple #1
0
        protected ConnectionCloseEventArgs GetConnectionCloseEventArgsFromPayload(byte[] payload)
        {
            if (payload.Length >= 2)
            {
                using (MemoryStream stream = new MemoryStream(payload))
                {
                    ushort code = BinaryReaderWriter.ReadUShortExactly(stream, false);

                    try
                    {
                        WebSocketCloseCode closeCode = (WebSocketCloseCode)code;

                        if (payload.Length > 2)
                        {
                            string reason = Encoding.UTF8.GetString(payload, 2, payload.Length - 2);
                            return(new ConnectionCloseEventArgs(closeCode, reason));
                        }
                        else
                        {
                            return(new ConnectionCloseEventArgs(closeCode, null));
                        }
                    }
                    catch (InvalidCastException)
                    {
                        _logger.Warning(this.GetType(), "Close code {0} not recognised", code);
                        return(new ConnectionCloseEventArgs(WebSocketCloseCode.Normal, null));
                    }
                }
            }

            return(new ConnectionCloseEventArgs(WebSocketCloseCode.Normal, null));
        }
Exemple #2
0
        private static void OnClose(WebSocketCloseCode closecode)
        {
            Disconnect(closecode.ToString());

            // Notify ConnectionWatchdog that connection was lost
            ConnectionWatchdog.OnClose(closecode);
        }
        public static void OnClose(WebSocketCloseCode closecode)
        {
            // if disconnected by error
            if (closecode == WebSocketCloseCode.Abnormal)
            {
                // if first time
                if (!IsTryingToReconnect)
                {
                    // init reconnection recursion
                    IsTryingToReconnect = true;
                    _reconnectTriesLeft = RECONNECT_TRIES;
                }

                // if in reconnection recursion
                if (_reconnectTriesLeft > 0)
                {
                    Reconnect();
                }
                // if no more tries left
                else
                {
                    Debug.Log("No more tries left. Stop reconnecting.");
                    IsTryingToReconnect = false;
                }
            }
            else // if connection is Ok
            {
                IsTryingToReconnect = false;
            }
        }
 //TODO: Handle code better.
 public async Task Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)
 {
     if (State == WebSocketState.Open)
     {
         await m_Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
     }
 }
Exemple #5
0
        /// <summary>
        /// Gets the connection close event arguments from payload.
        /// </summary>
        /// <param name="payload">The payload.</param>
        /// <returns></returns>
        private ConnectionClosedEventArgs GetConnectionCloseEventArgsFromPayload(byte[] payload)
        {
            if (payload.Length >= 2)
            {
                using (MemoryStream stream = new MemoryStream(payload))
                {
                    ushort code = StreamHelper.ReadUShortExactly(stream, false);

                    try
                    {
                        WebSocketCloseCode closeCode = (WebSocketCloseCode)code;

                        if (payload.Length > 2)
                        {
                            string reason = Encoding.UTF8.GetString(payload, 2, payload.Length - 2);
                            return(new ConnectionClosedEventArgs(closeCode, reason));
                        }

                        return(new ConnectionClosedEventArgs(closeCode, null));
                    }
                    catch (InvalidCastException)
                    {
                        return(new ConnectionClosedEventArgs(WebSocketCloseCode.Normal, null));
                    }
                }
            }

            return(new ConnectionClosedEventArgs(WebSocketCloseCode.Normal, null));
        }
Exemple #6
0
 private static void OnClose(WebSocketCloseCode closecode)
 {
     Debug.Log("Accounts server connection closed:\n" + closecode);
     mySocket     = null;
     IsConnected  = false;
     IsConnecting = false;
     _bufferedMessages.Clear();
 }
Exemple #7
0
        protected void OnDisconnected(WebSocketCloseCode error)
        {
            DebugUtility.LogTrace(LoggerTags.Online, "{0} Disconnected : {1}", mHost, error);

            if (onDisconnected != null)
            {
                onDisconnected(error.ToNetCode());
            }
        }
Exemple #8
0
        /// <summary>
        /// Close WebSocket connection with optional status code and reason.
        /// </summary>
        /// <param name="code">Close status code.</param>
        /// <param name="reason">Reason string.</param>
        public void Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)
        {
            int ret = WebSocketClose(this.instanceId, (int)code, reason);

            if (ret < 0)
            {
                throw WebSocketHelpers.GetErrorMessageFromCode(ret, null);
            }
        }
 public static WebSocketCloseCode ParseCloseCodeEnum(int closeCode)
 {
     if (WebSocketCloseCode.IsDefined(typeof(WebSocketCloseCode), closeCode))
     {
         return((WebSocketCloseCode)closeCode);
     }
     else
     {
         return(WebSocketCloseCode.Undefined);
     }
 }
Exemple #10
0
    private void OnLeftRoom(WebSocketCloseCode CloseCode)
    {
        if (LeftRoom != null)
        {
            LeftRoom(CloseCode);

            room = null;

            Debug.Log($"Left room!");
        }
    }
Exemple #11
0
    private void OnLeaveRoom(WebSocketCloseCode code)
    {
        LSLog.Log("ROOM: ON LEAVE =- Reason: " + code);
        _pingThread.Abort();
        _pingThread = null;
        _room       = null;

        if (code != WebSocketCloseCode.Normal && !string.IsNullOrEmpty(_lastRoomId))
        {
            JoinRoomId(_lastRoomId);
        }
    }
Exemple #12
0
        private void OnClose(WebSocketCloseCode closeCode)
        {
            collection.Unset(MessageCodes.EnteredScene);
            collection.Unset(MessageCodes.ChangeScene);
            collection.Unset(MessageCodes.GameObjectAdded);
            collection.Unset(MessageCodes.GameObjectRemoved);
            collection.Unset(MessageCodes.PositionChanged);
            collection.Unset(MessageCodes.AnimationStateChanged);
            collection.Unset(MessageCodes.Attacked);
            collection.Unset(MessageCodes.BubbleNotification);

            Disconnected?.Invoke();
        }
Exemple #13
0
        public void Close(WebSocketCloseCode closeCode, string closeReason)
        {
            if (State == WebSocketState.Closed || State == WebSocketState.None)
            {
                return;
            }

            var priorState = Interlocked.Exchange(ref _state, _closing);

            switch (priorState)
            {
            case _connected:
            {
                var closingHandshake = new CloseFrame(closeCode, closeReason).ToArray(_frameBuilder);
                try
                {
                    if (_stream.CanWrite)
                    {
                        StartClosingTimer();
                        var ar = _stream.BeginWrite(closingHandshake, 0, closingHandshake.Length, null, _stream);
                        if (!ar.AsyncWaitHandle.WaitOne(ConnectTimeout))
                        {
                            InternalClose(true);
                            throw new TimeoutException(string.Format(
                                                           "Closing handshake with remote [{0}] timeout [{1}].", RemoteEndPoint, ConnectTimeout));
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ShouldThrow(ex))
                    {
                        throw;
                    }
                }
                return;
            }

            case _connecting:
            case _closing:
            {
                InternalClose(true);
                return;
            }

            case _disposed:
            case _none:
            default:
                return;
            }
        }
    private void OnLeaveRoom(int code)
    {
        WebSocketCloseCode closeCode = WebSocketHelpers.ParseCloseCodeEnum(code);

        LSLog.Log(string.Format("ROOM: ON LEAVE =- Reason: {0} ({1})", closeCode, code));
        _pingThread.Abort();
        _pingThread = null;
        _room       = null;

        if (closeCode != WebSocketCloseCode.Normal && !string.IsNullOrEmpty(_lastRoomId))
        {
            JoinRoomId(_lastRoomId);
        }
    }
Exemple #15
0
        public static ENetCode ToNetCode(this WebSocketCloseCode code)
        {
            switch (code)
            {
            case WebSocketCloseCode.NotSet:
                return(ENetCode.WSNotSet);

            case WebSocketCloseCode.Normal:
                return(ENetCode.WSNormal);

            case WebSocketCloseCode.Away:
                return(ENetCode.WSAway);

            case WebSocketCloseCode.ProtocolError:
                return(ENetCode.WSProtocolError);

            case WebSocketCloseCode.UnsupportedData:
                return(ENetCode.WSUnsupportedData);

            case WebSocketCloseCode.Undefined:
                return(ENetCode.WSUndefined);

            case WebSocketCloseCode.NoStatus:
                return(ENetCode.WSNoStatus);

            case WebSocketCloseCode.Abnormal:
                return(ENetCode.WSAbnormal);

            case WebSocketCloseCode.InvalidData:
                return(ENetCode.WSInvalidData);

            case WebSocketCloseCode.PolicyViolation:
                return(ENetCode.WSPolicyViolation);

            case WebSocketCloseCode.TooBig:
                return(ENetCode.WSTooBig);

            case WebSocketCloseCode.MandatoryExtension:
                return(ENetCode.WSMandatoryExtension);

            case WebSocketCloseCode.ServerError:
                return(ENetCode.WSServerError);

            case WebSocketCloseCode.TlsHandshakeFailure:
                return(ENetCode.WSTlsHandshakeFailure);
            }
            return(ENetCode.WSNotSet);
        }
Exemple #16
0
        internal WebSocketCloseFrame(WebSocketFrameHeader head, Stream stream) : base(head, stream)
        {
            if (Data.Length > 1)
            {
                CloseCode = (WebSocketCloseCode)ByteUtil.ReadInt16(Data, 0);
            }
            else
            {
                CloseCode = WebSocketCloseCode.None;
            }

            if (Data.Length > 2)
            {
                Message = ByteUtil.ReadUtf8(Data, 2, Data.Length - 2);
            }
        }
Exemple #17
0
        public async Task Close(WebSocketCloseCode closeCode, string closeReason)
        {
            if (State == WebSocketState.Closed || State == WebSocketState.None)
            {
                return;
            }

            var priorState = Interlocked.Exchange(ref _state, _closing);

            switch (priorState)
            {
            case _connected:
            {
                var closingHandshake = new CloseFrame(closeCode, closeReason, false).ToArray(_frameBuilder);
                try
                {
                    if (_stream.CanWrite)
                    {
                        await _stream.WriteAsync(closingHandshake, 0, closingHandshake.Length);

                        StartClosingTimer();
#if DEBUG
                        _log.DebugFormat("Session [{0}] sends server side close frame [{1}] [{2}].", this, closeCode, closeReason);
#endif
                    }
                }
                catch (Exception ex) when(!ShouldThrow(ex))
                {
                }
                return;
            }

            case _connecting:
            case _closing:
            {
                await Close();

                return;
            }

            case _disposed:
            case _none:
            default:
                return;
            }
        }
        /// <summary>
        /// Close WebSocket connection with optional status code and reason.
        /// </summary>
        /// <param name="code">Close status code.</param>
        /// <param name="reason">Reason string.</param>
        public void Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)
        {
            // Check state
            if (this.ws.ReadyState == WebSocketSharp.WebSocketState.Closing)
            {
                throw new WebSocketInvalidStateException("WebSocket is already closing.");
            }

            if (this.ws.ReadyState == WebSocketSharp.WebSocketState.Closed)
            {
                throw new WebSocketInvalidStateException("WebSocket is already closed.");
            }
            try
            {
                this.ws.CloseAsync((ushort)code, reason);
            }
            catch (Exception e)
            {
                throw new WebSocketUnexpectedException("Failed to close the connection.", e);
            }
        }
Exemple #19
0
        /// <summary>
        /// Sends a close frame to the remote endpoint.  After calling this, you should close the underlying TCP connection.
        /// </summary>
        /// <param name="closeCode">The reason for the close. Note that some of the <see cref="WebSocketCloseCode"/> values are not intended to be sent.</param>
        /// <param name="message">A message to include in the close frame.  You can assume this message will not be shown to the user.  The message may be truncated to ensure the UTF8-Encoded length is 125 bytes or less.</param>
        public void Send(WebSocketCloseCode closeCode, string message = null)
        {
            if (sentCloseCode || closeCode == WebSocketCloseCode.None || closeCode == WebSocketCloseCode.TLSHandshakeFailed || closeCode == WebSocketCloseCode.ConnectionLost)
            {
                return;
            }

            byte[] msgBytes;
            if (message == null)
            {
                msgBytes = new byte[0];
            }
            else
            {
                if (message.Length > 125)
                {
                    message = message.Remove(125);
                }

                msgBytes = ByteUtil.Utf8NoBOM.GetBytes(message);
                while (msgBytes.Length > 125 && message.Length > 0)
                {
                    message  = message.Remove(message.Length - 1);
                    msgBytes = ByteUtil.Utf8NoBOM.GetBytes(message);
                }
                if (message.Length == 0)
                {
                    msgBytes = new byte[0];
                }
            }

            byte[] payload = new byte[2 + msgBytes.Length];
            ByteUtil.WriteUInt16((ushort)closeCode, payload, 0);
            Array.Copy(msgBytes, 0, payload, 2, msgBytes.Length);

            SendFrame(WebSocketOpcode.Close, payload);

            sentCloseCode = true;
        }
Exemple #20
0
 public void Close(WebSocketCloseCode closeCode)
 {
     Close(closeCode, null);
 }
Exemple #21
0
 void handleClose(WebSocketCloseCode closeCode)
 {
     callbackMessage("Disconnected");
     Debug.Log("socket close: " + closeCode);
 }
        public async Task Close(WebSocketCloseCode closeCode, string closeReason)
        {
            if (State == WebSocketState.Closed || State == WebSocketState.None)
                return;

            var priorState = Interlocked.Exchange(ref _state, _closing);
            switch (priorState)
            {
                case _connected:
                    {
                        var closingHandshake = new CloseFrame(closeCode, closeReason, false).ToArray(_frameBuilder);
                        try
                        {
                            if (_stream.CanWrite)
                            {
                                await _stream.WriteAsync(closingHandshake, 0, closingHandshake.Length);
                                StartClosingTimer();
#if DEBUG
                                _log.DebugFormat("Session [{0}] sends server side close frame [{1}] [{2}].", this, closeCode, closeReason);
#endif
                            }
                        }
                        catch (Exception ex) when (!ShouldThrow(ex)) { }
                        return;
                    }
                case _connecting:
                case _closing:
                    {
                        await Close();
                        return;
                    }
                case _disposed:
                case _none:
                default:
                    return;
            }
        }
 public async Task Close(WebSocketCloseCode closeCode)
 {
     await Close(closeCode, null);
 }
Exemple #24
0
        public async Task Receive()
        {
            WebSocketCloseCode closeCode = WebSocketCloseCode.Abnormal;

            await new WaitForBackgroundThread();

            ArraySegment <byte> buffer = new ArraySegment <byte>(new byte[8192]);

            try
            {
                while (m_Socket.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    if (m_CancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                    WebSocketReceiveResult result = null;
                    using (var ms = new MemoryStream())
                    {
                        do
                        {
                            result = await m_Socket.ReceiveAsync(buffer, m_CancellationToken);

                            ms.Write(buffer.Array, buffer.Offset, result.Count);
                        }while (!result.EndOfMessage);

                        ms.Seek(0, SeekOrigin.Begin);

                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            m_MessageListMutex.WaitOne();
                            m_MessageList.Add(ms.ToArray());
                            m_MessageListMutex.ReleaseMutex();
                        }
                        else if (result.MessageType == WebSocketMessageType.Binary)
                        {
                            m_MessageListMutex.WaitOne();
                            m_MessageList.Add(ms.ToArray());
                            m_MessageListMutex.ReleaseMutex();
                        }
                        else if (result.MessageType == WebSocketMessageType.Close)
                        {
                            await Close();

                            closeCode = WebSocketHelpers.ParseCloseCodeEnum((int)result.CloseStatus);
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Log("Exception while waiting for messages: " + e.Message);
                m_TokenSource.Cancel();
                m_TokenSource = null;
            }
            finally
            {
                await new WaitForUpdate();
                OnClose?.Invoke(closeCode);
            }
        }
Exemple #25
0
        public void Close(WebSocketCloseCode closeCode, string closeReason)
        {
            if (State == WebSocketState.Closed || State == WebSocketState.None)
                return;

            var priorState = Interlocked.Exchange(ref _state, _closing);
            switch (priorState)
            {
                case _connected:
                    {
                        var closingHandshake = new CloseFrame(closeCode, closeReason).ToArray(_frameBuilder);
                        try
                        {
                            if (_stream.CanWrite)
                            {
                                StartClosingTimer();
                                var ar = _stream.BeginWrite(closingHandshake, 0, closingHandshake.Length, null, _stream);
                                if (!ar.AsyncWaitHandle.WaitOne(ConnectTimeout))
                                {
                                    InternalClose(true);
                                    throw new TimeoutException(string.Format(
                                        "Closing handshake with remote [{0}] timeout [{1}].", RemoteEndPoint, ConnectTimeout));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ShouldThrow(ex))
                                throw;
                        }
                        return;
                    }
                case _connecting:
                case _closing:
                    {
                        InternalClose(true);
                        return;
                    }
                case _disposed:
                case _none:
                default:
                    return;
            }
        }
Exemple #26
0
        /// <summary>
        /// Tries to parse a byte[] header into a SocketDataFrame object.
        /// Returns a null reference if object cannot be parsed
        /// </summary>
        /// <param name="headerBytes">A byte array containing the read frame header bytes</param>
        /// <param name="socket">A reference to the socket from which to parse the SocketFrame</param>
        /// <returns>
        /// If pasrse is successful, an Object of a type that is derived from SocketFrame.abstract Returns a null pointer otherwise.
        /// </returns>
        /// <remarks>
        /// This method is not exactly like the Int*.TryParse() methods as it doesn't take an 'out' parameter and return a
        /// boolean value but rather returns either the parsed object reference or a null reference, which means that callers of this method need to check
        /// for null before using the return value.
        /// Furthermore, if the parse is successful, a caller should check the type of the object that is returned to, for example,
        /// differenciate between a SocketDataFrame and a SocketControlFrame, which are both derived from SocketFrame.
        /// It is necessary to pass a reference to the socket because of the way the WebSocket protocol is made.abstract It is impossible to know
        /// the length of the frame before having parsed the headers hence it is possible that more bytes will need to be read from the socket buffer.
        /// </remarks>
        public static WebSocketFrame TryParse(byte[] headerBytes, Socket socket)
        {
            int             headerSize    = headerBytes.Length;
            bool            fin           = (headerBytes[0] >> 7) != 0;
            WebSocketOPCode opcode        = (WebSocketOPCode)((byte)(headerBytes[0] & 0b00001111));
            bool            masked        = (headerBytes[1] & 0b10000000) != 0;
            ushort          contentLength = (ushort)(headerBytes[1] & 0b01111111);

            if (contentLength <= 126)
            {
                if (contentLength == 126)
                {
                    headerSize = 4;
                    byte[] largerHeader = new byte[headerSize];
                    headerBytes.CopyTo(largerHeader, 0);
                    // Read next two bytes and interpret them as the content length
                    socket.Receive(largerHeader, 2, 2, SocketFlags.None);
                    contentLength = (ushort)(largerHeader[2] <<  8 | largerHeader[3]);
                }

                byte[] maskingKey = new byte[4];
                socket.Receive(maskingKey);

                byte[] contentBuffer = new byte[contentLength];
                if (contentLength > 0)
                {
                    socket.Receive(contentBuffer);
                }

                WebSocketFrame frame;
                if (opcode == WebSocketOPCode.Text || opcode == WebSocketOPCode.Binary)
                {
                    frame = new WebSocketDataFrame(fin, masked, contentBuffer, (WebSocketDataFrame.DataFrameType)opcode, ApplyMask(contentBuffer, maskingKey));
                }
                else if (opcode == WebSocketOPCode.Close)
                {
                    WebSocketCloseFrame closeFrame = new WebSocketCloseFrame();
                    if (contentLength >= 2)
                    {
                        byte[]             unmasked  = ApplyMask(contentBuffer, maskingKey);
                        WebSocketCloseCode closeCode = (WebSocketCloseCode)BitConverter.ToUInt16(unmasked);
                        closeFrame.CloseCode = closeCode;

                        if (contentLength > 2)
                        {
                            byte[] closeReasonBytes = new byte[contentLength - 2];
                            Array.Copy(contentBuffer, 2, closeReasonBytes, 0, closeReasonBytes.Length);
                            closeFrame.CloseReason = System.Text.Encoding.UTF8.GetString(closeReasonBytes);
                        }
                    }

                    frame = closeFrame;
                }
                else
                {
                    frame = new WebSocketControlFrame(fin, masked, (WebSocketOPCode)opcode);
                }

                return(frame);
            }

            return(null);
        }
Exemple #27
0
 protected void _OnClose(WebSocketCloseCode code)
 {
     ProcessingMessageQueue = false;
     IsOpen = false;
 }
 protected void _OnClose(WebSocketCloseCode code)
 {
     IsOpen = false;
 }
Exemple #29
0
 public async Task Close(WebSocketCloseCode closeCode)
 {
     await Close(closeCode, null);
 }
        public async Task Close(WebSocketCloseCode closeCode, string closeReason)
        {
            if (State == WebSocketState.Closed || State == WebSocketState.None)
                return;

            var priorState = Interlocked.Exchange(ref _state, _closing);
            switch (priorState)
            {
                case _connected:
                    {
                        var closingHandshake = new CloseFrame(closeCode, closeReason).ToArray(_frameBuilder);
                        try
                        {
                            if (_stream.CanWrite)
                            {
                                StartClosingTimer();
#if DEBUG
                                _log.DebugFormat("Send client side close frame [{0}] [{1}].", closeCode, closeReason);
#endif
                                var awaiter = _stream.WriteAsync(closingHandshake, 0, closingHandshake.Length);
                                if (!awaiter.Wait(ConnectTimeout))
                                {
                                    await InternalClose(true);
                                    throw new TimeoutException(string.Format(
                                        "Closing handshake with [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
                                }
                            }
                        }
                        catch (Exception ex) when (!ShouldThrow(ex)) { }
                        return;
                    }
                case _connecting:
                case _closing:
                    {
                        await InternalClose(true);
                        return;
                    }
                case _disposed:
                case _none:
                default:
                    return;
            }
        }
Exemple #31
0
 public void Close(WebSocketCloseCode closeCode)
 {
     Close(closeCode, null);
 }
Exemple #32
0
 protected virtual void OnWebSocketClose(WebSocketCloseCode webSocketCloseCode)
 {
     logger.Log("WebSocket Closed!");
 }
Exemple #33
0
 public CloseFrame(WebSocketCloseCode closeCode, string closeReason, bool isMasked = true)
     : this(isMasked)
 {
     this.CloseCode = closeCode;
     this.CloseReason = closeReason;
 }
Exemple #34
0
 private void OnClose(WebSocketCloseCode code)
 {
     Debug.Log("WS closed with code: " + code.ToString());
     //always reconnect
     Connect();
 }
 private void _Close(WebSocketCloseCode closeCode)
 {
     CloseEvent();
 }
Exemple #36
0
 public ConnectionCloseEventArgs(WebSocketCloseCode code, string reason)
 {
     Code   = code;
     Reason = reason;
 }