示例#1
0
 /// <summary>
 /// Fired when a ping was received
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 public async Task OnPingAsync(PingNotificationBody e)
 {
     if (Ping != null)
     {
         await Ping.Invoke(e);
     }
 }
        protected async Task ProcessMessage()
        {
            var messages = await GetMessages().ConfigureAwait(false);

            if (messages is null)
            {
                return;
            }

            foreach (var message in messages)
            {
                switch (message.Code)
                {
                case WebSocketFrame.OpCode.ContinuationFrame:
                    ContinuationFrameReceived?.Invoke(this, Encoding.UTF8.GetString(message.Data));
                    break;

                case WebSocketFrame.OpCode.TextFrame:
                    if (message.Data.Length > 0)
                    {
                        MessageReceived?.Invoke(this, Encoding.UTF8.GetString(message.Data));
                    }
                    break;

                case WebSocketFrame.OpCode.BinaryFrame:
                    BinaryMessageReceived?.Invoke(this, message.Data);
                    break;

                case WebSocketFrame.OpCode.ConnectionClose:
                    TcpClient.Close();
                    var code = BitConverter.ToUInt16(message.Data.Take(2).Reverse().ToArray(), 0);
                    ConnectionClosed?.Invoke(this, (WebSocketFrame.CloseStatusCode)code);
                    break;

                case WebSocketFrame.OpCode.Ping:
                    Ping?.Invoke(this, null);
                    break;

                case WebSocketFrame.OpCode.Pong:
                    Pong?.Invoke(this, null);
                    break;

                default:
                    Console.WriteLine("Not supported command.");
                    break;
                }
            }
        }
示例#3
0
        /// <inheritdoc />
        public void Add(T item)
        {
            Validate(item);
            bool q;
            PingEventArgs <T> e;

            rwlock.EnterWriteLock();
            try
            {
                q = _Add(item, out e);
            }
            finally
            {
                rwlock.ExitWriteLock();
            }

            // Could not add.  Ping oldest contacts.
            if (!q)
            {
                Ping?.Invoke(this, e);
            }
        }
示例#4
0
        private protected unsafe void DeserializeData(uint commandid, byte[] data, int offset, int length,
                                                      uint responseid)
        {
            if (responseid != 0)
            {
                TaskCompletionSource <Packet> cs;
                bool lockTaken = false;
                try
                {
                    _lockTaskCompletionSources.Enter(ref lockTaken);
                    if (_taskCompletionSources.TryGetValue(responseid, out cs))
                    {
                        _taskCompletionSources.Remove(responseid);
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        _lockTaskCompletionSources.Exit(false);
                    }
                }
                if (cs != null && !cs.TrySetResult(
                        new Packet(data, offset, length)))
                {
                    ByteArrayPool.Return(data);
                }
                return;
            }
            switch (commandid)
            {
            case CommandID.PING:
            {
                PingPacket pingStruct;
                fixed(byte *ptr = data)
                {
                    pingStruct = *(PingPacket *)(ptr + offset);
                }

                Ping?.Invoke(pingStruct);
                break;
            }

            case CommandID.CONNECT:
            {
                data.FromBytesUnsafe(offset, out ConnectPacket connectPacket);
                fixed(byte *ptr = _connectChecksum)
                {
                    if (SequenceEqual(connectPacket.Checksum, ptr, 16))
                    {
                        _manuelResetEvent.Set();
                    }
                }

                break;
            }

            default:
            {
                if (commandid <= Constants.USER_COMMAND_LIMIT &&
                    _dataReceivedCallbacks.TryGetValue(commandid, out ClientEventEntry cee))
                {
                    Packet packet = new Packet(data, offset, length);
                    ThreadPool.QueueUserWorkItem(
                        x =>
                        {
                            object res = cee._deserialize(in packet);
                            ByteArrayPool.Return(data);

                            if (res != null)
                            {
                                cee.Raise(this, res);
                            }
                        });
                    return;
                }
                break;
            }
            }
            ByteArrayPool.Return(data);
        }
示例#5
0
 internal void OnPing(PingMessage message) => Ping?.Invoke(message);
示例#6
0
 private void PingTimerOnElapsed(object sender, ElapsedEventArgs e)
 {
     SendPing();
     pongTimeoutTimer.Start();
     Ping?.Invoke(this, System.EventArgs.Empty);
 }
示例#7
0
 public static void Write(string message, Ping ping, bool error = false)
 {
     Console.WriteLine(message);
     ping?.Invoke(message, error);
 }
示例#8
0
        private void ProcessReceive(SocketAsyncEventArgs ioEventArgs)
        {
            var dataToken = (WSDataToken)ioEventArgs.UserToken;
            var socket    = (WebSocket)dataToken.Socket;

            if (ioEventArgs.BytesTransferred == 0)
            {
                //对方主动关闭socket
                Closing(ioEventArgs, Opcode.Empty);
                return;
            }
            if (ioEventArgs.SocketError != SocketError.Success)
            {
                //Socket错误
                Closing(ioEventArgs);
                return;
            }

            bool needPostAnother = TryReceiveMessage(ioEventArgs, out List <DataMessage> messages, out bool hasHandshaked);

            if (hasHandshaked)
            {
                Connected?.Invoke(this, new WebSocketEventArgs(socket));
            }
            if (messages != null)
            {
                foreach (var message in messages)
                {
                    try
                    {
                        switch (message.Opcode)
                        {
                        case Opcode.Close:
                            Closing(ioEventArgs);
                            needPostAnother = false;
                            break;

                        case Opcode.Ping:
                            Ping?.Invoke(this, new WebSocketEventArgs(socket, message));
                            break;

                        case Opcode.Pong:
                            Pong?.Invoke(this, new WebSocketEventArgs(socket, message));
                            break;

                        default:
                            DataReceived?.Invoke(this, new WebSocketEventArgs(socket, message));
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error("OnDataReceived error:{0}", ex);
                    }
                }
            }
            if (needPostAnother)
            {
                if (socket.IsClosed)
                {
                    ResetSAEAObject(ioEventArgs);
                }
                else
                {
                    PostReceive(ioEventArgs);
                }
            }
        }
示例#9
0
 public void PingProxyHandler()
 {
     Ping?.Invoke();
 }
示例#10
0
        private async void ReceiverLoop(object obj)
        {
            WebSocketReceiveResult r;
            var buffer        = new byte[BufferSize];
            var bufferSegment = new ArraySegment <byte>(buffer);

            pingRequestDeadline = Environment.TickCount + (int)PingInterval.TotalMilliseconds;
            pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds;
            Task <WebSocketReceiveResult> tReceive = null;
            Task tPing = null;

            while (innerWebSocket.State == WebSocketState.Open)
            {
                try
                {
                    if (tReceive == null)
                    {
                        tReceive = innerWebSocket.ReceiveAsync(bufferSegment, CancellationToken.None);
                    }
                }
                catch (ObjectDisposedException)
                {
                    break;
                }
                if (tPing == null)
                {
                    tPing = Task.Delay(Math.Max(0, Math.Min(pingRequestDeadline - Environment.TickCount, pongTimeoutDeadline - Environment.TickCount)));
                }
                var t = await Task.WhenAny(tReceive, tPing);

                if (t == tReceive)
                {
                    try
                    {
                        r        = await tReceive;
                        tReceive = null;
                    }
                    catch (WebSocketException)
                    {
                        // Disconnection?
                        break;
                    }

                    switch (r.MessageType)
                    {
                    case WebSocketMessageType.Text:
                        if (r.Count > 0)
                        {
                            // Defalut engine.io protocol
                            switch (buffer[0])
                            {
                            case (byte)'3':         // Server Pong
                                pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds;
                                Ping?.Invoke(this, new PingEventArgs(pingRequestAt, Environment.TickCount));
                                break;

                            case (byte)'4':         // Message
                                if (r.Count > 1)
                                {
                                    // Defalut socket.io protocol
                                    switch (buffer[1])
                                    {
                                    case (byte)'0':             // Connect
                                    case (byte)'1':             // Disconnect
                                        // Ignored
                                        break;

                                    case (byte)'2':             // Event
                                        try
                                        {
                                            var text = Encoding.UTF8.GetString(bufferSegment.Array, bufferSegment.Offset + 2, r.Count - 2);
                                            IncomingEvent?.Invoke(this, new IncomingEventEventArgs(text));
                                        }
                                        catch (ArgumentException) { }
                                        break;

                                    case (byte)'3':             // Ack
                                    case (byte)'4':             // Error
                                    case (byte)'5':             // Binary_Event
                                    case (byte)'6':             // Binary_Ack
                                        // Ignored
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                        break;

                    case WebSocketMessageType.Binary:
                    case WebSocketMessageType.Close:
                    default:
                        // Nothing to handle
                        break;
                    }
                }
                else
                {
                    if (Environment.TickCount - pingRequestDeadline >= 0)
                    {
                        if (Interlocked.CompareExchange(ref pingRequest, 1, 0) == 0)
                        {
                            pingRequest = 1;
                            WakeSenderLoop();
                            pingRequestDeadline = Environment.TickCount + (int)PingInterval.TotalMilliseconds;
                            pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds;
                        }
                    }
                    if (Environment.TickCount - pongTimeoutDeadline >= 0)
                    {
                        // Ping timeout
                        try
                        {
                            await innerWebSocket.CloseAsync(WebSocketCloseStatus.EndpointUnavailable, "Ping timeout", CancellationToken.None);
                        }
                        catch (WebSocketException) { }
                        catch (ObjectDisposedException) { }
                        break;
                    }
                }
            }

            Disconnect?.Invoke(this, EventArgs.Empty);
        }