예제 #1
0
        void IManager.OnPacket(Packet packet)
        {
            if (this.State == SocketManager.States.Closed)
            {
                return;
            }
            TransportEventTypes transportEvent = packet.TransportEvent;

            if (transportEvent != TransportEventTypes.Ping)
            {
                if (transportEvent == TransportEventTypes.Pong)
                {
                    this.LastPongReceived = DateTime.UtcNow;
                }
            }
            else
            {
                ((IManager)this).SendPacket(new Packet(TransportEventTypes.Pong, SocketIOEventTypes.Unknown, "/", string.Empty, 0, 0));
            }
            Socket socket = null;

            if (this.Namespaces.TryGetValue(packet.Namespace, out socket))
            {
                ((ISocket)socket).OnPacket(packet);
            }
            else
            {
                HTTPManager.Logger.Warning("SocketManager", "Namespace \"" + packet.Namespace + "\" not found!");
            }
        }
예제 #2
0
 public TransportEventArgs(TransportEventTypes type, byte[] data, Object context, Int64 localSocketId)
 {
     mType          = type;
     mData          = data;
     mContext       = context;
     mLocalSocketId = localSocketId;
 }
예제 #3
0
        /// <summary>
        /// Encodes this packet to a Socket.IO formatted string.
        /// </summary>
        internal string Encode()
        {
            StringBuilder builder = new StringBuilder();

            // Set to Message if not set, and we are sending attachments
            if (this.TransportEvent == TransportEventTypes.Unknown && this.AttachmentCount > 0)
                this.TransportEvent = TransportEventTypes.Message;

            if (this.TransportEvent != TransportEventTypes.Unknown)
                builder.Append(((int)this.TransportEvent).ToString());

            // Set to BinaryEvent if not set, and we are sending attachments
            if (this.SocketIOEvent == SocketIOEventTypes.Unknown && this.AttachmentCount > 0)
                this.SocketIOEvent = SocketIOEventTypes.BinaryEvent;

            if (this.SocketIOEvent != SocketIOEventTypes.Unknown)
                builder.Append(((int)this.SocketIOEvent).ToString());

            if (this.SocketIOEvent == SocketIOEventTypes.BinaryEvent || this.SocketIOEvent == SocketIOEventTypes.BinaryAck)
            {
                builder.Append(this.AttachmentCount.ToString());
                builder.Append("-");
            }

            // Add the namespace. If there is any other then the root nsp ("/")
            // then we have to add a trailing "," if we have more data.
            bool nspAdded = false;
            if (this.Namespace != "/")
            {
                builder.Append(this.Namespace);
                nspAdded = true;
            }

            // ack id, if any
            if (this.Id != 0)
            {
                if (nspAdded)
                {
                    builder.Append(",");
                    nspAdded = false;
                }

                builder.Append(this.Id.ToString());
            }

            // payload
            if (!string.IsNullOrEmpty(this.Payload))
            {
                if (nspAdded)
                {
                    builder.Append(",");
                    nspAdded = false;
                }

                builder.Append(this.Payload);
            }

            return builder.ToString();
        }
예제 #4
0
 /// <summary>
 /// Internal constructor. Don't use it directly!
 /// </summary>
 public Packet(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, string payload, int attachment = 0, int id = 0)
 {
     this.TransportEvent  = transportEvent;
     this.SocketIOEvent   = packetType;
     this.Namespace       = nsp;
     this.Payload         = payload;
     this.AttachmentCount = attachment;
     this.Id = id;
 }
예제 #5
0
 internal Packet(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, string payload, int attachment = 0, int id = 0)
 {
     TransportEvent  = transportEvent;
     SocketIOEvent   = packetType;
     Namespace       = nsp;
     Payload         = payload;
     AttachmentCount = attachment;
     Id = id;
 }
예제 #6
0
        /// <summary>
        /// Parse the packet from a server sent textual data. The Payload will be the raw json string.
        /// </summary>
        internal void Parse(string from)
        {
            int idx = 0;
            this.TransportEvent = (TransportEventTypes)(int)char.GetNumericValue(from, idx++);

            if (from.Length > idx && char.GetNumericValue(from, idx) >= 0.0)
                this.SocketIOEvent = (SocketIOEventTypes)(int)char.GetNumericValue(from, idx++);
            else
                this.SocketIOEvent = SocketIOEventTypes.Unknown;

            // Parse Attachment
            if (this.SocketIOEvent == SocketIOEventTypes.BinaryEvent || this.SocketIOEvent == SocketIOEventTypes.BinaryAck)
            {
                int endIdx = from.IndexOf('-', idx);
                if (endIdx == -1)
                    endIdx = from.Length;

                int attachment = 0;
                int.TryParse(from.Substring(idx, endIdx - idx), out attachment);
                this.AttachmentCount = attachment;
                idx = endIdx + 1;
            }

            // Parse Namespace
            if (from.Length > idx && from[idx] == '/')
            {
                int endIdx = from.IndexOf(',', idx);
                if (endIdx == -1)
                    endIdx = from.Length;

                this.Namespace = from.Substring(idx, endIdx - idx);
                idx = endIdx + 1;
            }
            else
                this.Namespace = "/";

            // Parse Id
            if (from.Length > idx && char.GetNumericValue(from[idx]) >= 0)
            {
                int startIdx = idx++;
                while (from.Length > idx && char.GetNumericValue(from[idx]) >= 0)
                    idx++;

                int id = 0;
                int.TryParse(from.Substring(startIdx, idx - startIdx), out id);
                this.Id = id;
            }

            // What left is the payload data
            if (from.Length > idx)
                this.Payload = from.Substring(idx);
            else
                this.Payload = string.Empty;
        }
예제 #7
0
        public IncomingPacket Parse(SocketManager manager, BufferSegment data, TransportEventTypes transportEvent = TransportEventTypes.Unknown)
        {
            IncomingPacket packet = IncomingPacket.Empty;

            if (PacketWithAttachment.Attachements == null)
            {
                PacketWithAttachment.Attachements = new List <BufferSegment>(PacketWithAttachment.AttachementCount);
            }
            PacketWithAttachment.Attachements.Add(data);

            if (PacketWithAttachment.Attachements.Count == PacketWithAttachment.AttachementCount)
            {
                packet = manager.Parser.MergeAttachements(manager, PacketWithAttachment);
                PacketWithAttachment = IncomingPacket.Empty;
            }

            return(packet);
        }
예제 #8
0
 private void OnPacket(Packet packet)
 {
     if (packet.AttachmentCount != 0 && !packet.HasAllAttachment)
     {
         PacketWithAttachment = packet;
     }
     else
     {
         TransportEventTypes transportEvent = packet.TransportEvent;
         if (transportEvent == TransportEventTypes.Message && packet.SocketIOEvent == SocketIOEventTypes.Connect && State == TransportStates.Opening)
         {
             State = TransportStates.Open;
             if (!((IManager)Manager).OnTransportConnected((ITransport)this))
             {
                 return;
             }
         }
         ((IManager)Manager).OnPacket(packet);
     }
 }
예제 #9
0
        private void OnPacket(Packet packet)
        {
            TransportEventTypes transportEvent = packet.TransportEvent;

            if (transportEvent == TransportEventTypes.Pong)
            {
                if (packet.Payload == "probe")
                {
                    HTTPManager.Logger.Information("WebSocketTransport", "\"probe\" packet received, sending Upgrade packet");
                    this.Send(new Packet(TransportEventTypes.Upgrade, SocketIOEventTypes.Event, "/", string.Empty, 0, 0));
                    this.State = TransportStates.Open;
                    if (((IManager)this.Manager).OnTransportConnected(this))
                    {
                        this.OnPacket(new Packet(TransportEventTypes.Message, SocketIOEventTypes.Connect, "/", string.Empty, 0, 0));
                        return;
                    }
                }
            }
            ((IManager)this.Manager).OnPacket(packet);
        }
예제 #10
0
        public IncomingPacket(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, int id)
        {
            this.TransportEvent = transportEvent;
            this.SocketIOEvent  = packetType;
            this.Namespace      = nsp;
            this.Id             = id;

            this.AttachementCount = 0;
            //this.ReceivedAttachements = 0;
            this.Attachements = null;

            if (this.SocketIOEvent != SocketIOEventTypes.Unknown)
            {
                this.EventName = EventNames.GetNameFor(this.SocketIOEvent);
            }
            else
            {
                this.EventName = EventNames.GetNameFor(this.TransportEvent);
            }

            this.DecodedArg = this.DecodedArgs = null;
        }
예제 #11
0
        private void ParseResponse(HTTPResponse resp)
        {
            try
            {
                if (resp == null || resp.Data == null || resp.Data.Length < 1)
                {
                    return;
                }

                int idx = 0;
                while (idx < resp.Data.Length)
                {
                    int endIdx = FindNextRecordSeparator(resp.Data, idx);
                    int length = endIdx - idx;

                    if (length <= 0)
                    {
                        break;
                    }

                    IncomingPacket packet = IncomingPacket.Empty;

                    if (resp.Data[idx] == 'b')
                    {
                        // First byte is the binary indicator('b'). We must skip it, so we advance our idx and also have to decrease length
                        idx++;
                        length--;
                        var base64Encoded = System.Text.Encoding.UTF8.GetString(resp.Data, idx, length);
                        var byteData      = Convert.FromBase64String(base64Encoded);
                        packet = this.Manager.Parser.Parse(this.Manager, new BufferSegment(byteData, 0, byteData.Length));
                    }
                    else
                    {
                        // It's the handshake data?
                        if (this.State == TransportStates.Opening)
                        {
                            TransportEventTypes transportEvent = (TransportEventTypes)(resp.Data[idx] - '0');
                            if (transportEvent == TransportEventTypes.Open)
                            {
                                var handshake = BestHTTP.JSON.LitJson.JsonMapper.ToObject <HandshakeData>(Encoding.UTF8.GetString(resp.Data, idx + 1, length - 1));
                                packet            = new IncomingPacket(TransportEventTypes.Open, SocketIOEventTypes.Unknown, "/", -1);
                                packet.DecodedArg = handshake;
                            }
                            else
                            {
                                // TODO: error?
                            }
                        }
                        else
                        {
                            packet = this.Manager.Parser.Parse(this.Manager, System.Text.Encoding.UTF8.GetString(resp.Data, idx, length));
                        }
                    }

                    if (!packet.Equals(IncomingPacket.Empty))
                    {
                        try
                        {
                            OnPacket(packet);
                        }
                        catch (Exception ex)
                        {
                            HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex, this.Manager.Context);
                            (Manager as IManager).EmitError(ex.Message + " " + ex.StackTrace);
                        }
                    }

                    idx = endIdx + 1;
                }
            }
            catch (Exception ex)
            {
                (Manager as IManager).EmitError(ex.Message + " " + ex.StackTrace);

                HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex, this.Manager.Context);
            }
        }
예제 #12
0
 public static string GetNameFor(TransportEventTypes transEvent)
 {
     return(TransportNames[(int)transEvent + 1]);
 }
 /// <summary>
 /// Internal constructor. Don't use it directly!
 /// </summary>
 internal Packet(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, string payload, int attachment = 0, int id = 0)
 {
     this.TransportEvent = transportEvent;
     this.SocketIOEvent = packetType;
     this.Namespace = nsp;
     this.Payload = payload;
     this.AttachmentCount = attachment;
     this.Id = id;
 }
예제 #14
0
 public static string GetNameFor(TransportEventTypes transEvent)
 {
     return TransportNames[(int)transEvent + 1];
 }
예제 #15
0
 public TransportEventArgs(TransportEventTypes type, byte[] data, Object context, Int64 localSocketId)
 {
     mType = type;
     mData = data;
     mContext = context;
     mLocalSocketId = localSocketId;
 }
예제 #16
0
 public OutgoingPacket CreateOutgoing(TransportEventTypes transportEvent, string payload)
 {
     return(new OutgoingPacket {
         Payload = "" + (char)('0' + (byte)transportEvent) + payload
     });
 }
예제 #17
0
 public static string GetNameFor(TransportEventTypes transEvent) =>
 TransportNames[((int)transEvent) + 1];
예제 #18
0
        public IncomingPacket Parse(SocketManager manager, BufferSegment data, TransportEventTypes transportEvent = TransportEventTypes.Unknown)
        {
            using (var stream = new System.IO.MemoryStream(data.Data, data.Offset, data.Count))
            {
                var buff = BufferPool.Get(MsgPackReader.DEFAULT_BUFFER_SIZE, true);
                try
                {
                    var context = new SerializationContext
                    {
                        Options = SerializationOptions.SuppressTypeInformation/*,
                                                                               * ExtensionTypeHandler = CustomMessagePackExtensionTypeHandler.Instance*/
                    };
                    IJsonReader reader = new MsgPackReader(stream, context, Endianness.BigEndian, buff);

                    reader.ReadObjectBegin();

                    int    type = -1, id = -1;
                    string nsp = null;

                    bool hasData = false, readData = false;

                    IncomingPacket packet = IncomingPacket.Empty;

READ:

                    while (reader.Token != JsonToken.EndOfObject)
                    {
                        string key = reader.ReadMember();

                        switch (key)
                        {
                        case "type":
                            type = reader.ReadByte();
                            break;

                        case "nsp":
                            nsp = reader.ReadString();
                            break;

                        case "id":
                            id = reader.ReadInt32();
                            break;

                        case "data":
                            if (!hasData)
                            {
                                hasData = true;
                                SkipData(reader, (SocketIOEventTypes)type);
                            }
                            else
                            {
                                readData = true;

                                packet = new IncomingPacket(transportEvent != TransportEventTypes.Unknown ? transportEvent : TransportEventTypes.Message, (SocketIOEventTypes)type, nsp, id);
                                (string eventName, object[] args) = ReadData(manager, packet, reader);

                                packet.EventName = eventName;
                                if (args != null)
                                {
                                    if (args.Length == 1)
                                    {
                                        packet.DecodedArg = args[0];
                                    }
                                    else
                                    {
                                        packet.DecodedArgs = args;
                                    }
                                }
                            }
                            break;
                        }
                    }

                    // type, nsp, id and data can come in any order. To read data strongly typed we need to know all the additional fields before processing the data field.
                    // In order to do it, when we first encounter the data field we skip it than we do a reset and an additional turn but reading the data too now.
                    if (hasData && !readData)
                    {
                        reader.Reset();
                        stream.Position = 0;
                        reader.ReadObjectBegin();

                        goto READ;
                    }

                    reader.ReadObjectEnd();

                    return(packet.Equals(IncomingPacket.Empty) ? new IncomingPacket(transportEvent != TransportEventTypes.Unknown ? transportEvent : TransportEventTypes.Message, (SocketIOEventTypes)type, nsp, id) : packet);
                }
                finally
                {
                    BufferPool.Release(buff);
                }
            }
        }