Exemple #1
0
 public Response Push(Frame frame)
 {
     lock (Sync)
     {
         if (frame.Opcode == 0 && IncomingOpcode == 0)
         {
             return(Response.MessageNotStarted);
         }
         if (frame.Opcode != 0 && IncomingOpcode != 0)
         {
             return(Response.MessageNotFinished);
         }
         if (frame.Opcode != 0)
         {
             IncomingOpcode = frame.Opcode;
         }
         IncomingMessage.Write(frame.Masked ? Frame.FlipMask(frame.Payload, frame.Mask) : frame.Payload);
         if (!frame.FIN)
         {
             return(Response.OK);
         }
         ulong length = IncomingMessage.BufferedReadable;
         OnCollect?.Invoke(new Message(IncomingOpcode, IncomingMessage.Read(), length));
         IncomingOpcode = 0;
         return(Response.Reset);
     }
 }
Exemple #2
0
        protected override bool HandleWritable(byte[] source)
        {
            Buffer.Write(source); ulong buffered;
            while ((buffered = Buffer.BufferedReadable) > 0)
            {
                switch (State)
                {
                case ParseState.Head:
                    if (buffered < 2)
                    {
                        return(true);
                    }
                    Incoming = new Frame(Reader.ReadUInt8(), Reader.ReadUInt8());
                    switch (Frame.GetXLengthSize(Incoming.Length))
                    {
                    case 0:
                        Incoming.ExtendedLength = Incoming.Length;
                        if (Incoming.Masked)
                        {
                            State = ParseState.Mask;
                        }
                        else if (Incoming.Length > 0)
                        {
                            State = ParseState.Payload;
                        }
                        else
                        {
                            Reset();
                        }
                        break;

                    case 2: State = ParseState.ExtendedLen2; break;

                    case 8: State = ParseState.ExtendedLen8; break;
                    }
                    break;

                case ParseState.ExtendedLen2:
                    if (buffered < 2)
                    {
                        return(true);
                    }
                    Incoming.ExtendedLength = Reader.ReadUInt16LE();
                    if (Incoming.Masked)
                    {
                        State = ParseState.Mask;
                    }
                    else if (Incoming.ExtendedLength > 0)
                    {
                        State = ParseState.Payload;
                    }
                    else
                    {
                        Reset();
                    }
                    break;

                case ParseState.ExtendedLen8:
                    if (buffered < 8)
                    {
                        return(true);
                    }
                    Incoming.ExtendedLength = Reader.ReadUInt64LE();
                    if (Incoming.Masked)
                    {
                        State = ParseState.Mask;
                    }
                    else if (Incoming.ExtendedLength > 0)
                    {
                        State = ParseState.Payload;
                    }
                    else
                    {
                        Reset();
                    }
                    break;

                case ParseState.Mask:
                    if (buffered < 4)
                    {
                        return(true);
                    }
                    Incoming.Mask = Buffer.Read(4);
                    State         = ParseState.Payload;
                    break;

                case ParseState.Payload:
                    if (buffered < Incoming.ExtendedLength)
                    {
                        return(true);
                    }
                    Incoming.Payload = Buffer.Read(Incoming.ExtendedLength);
                    Reset();
                    break;
                }
            }
            return(true);
        }