Пример #1
0
        private void ProcessRequest(ClientObject co)
        {
            Client.Request Req = new Client.Request()
            {
                Header = co.Header,
                Body   = co.Buffer.Count > 0?co.Buffer.ToArray():null,
                Client = co.EventArgs.AcceptSocket
            };
            Response Res = HandleRequest(Req);

            Res.Header.ContentLength = Res.Body != null ? Res.Body.Length : 0;
            Res.Header["Connection"] = KeepAlive ? "KeepAlive" : "Close";


            List <byte> buf = new List <byte>();

            buf.AddRange(Encoding.UTF8.GetBytes(Res.Header.ToHttpHeader()));
            buf.AddRange(Base.NewLineBytes);
            if (Res.Body != null && Res.Body.Length > 0)
            {
                buf.AddRange(Res.Body);
            }
            byte[] bts = buf.ToArray();
            System.Net.Sockets.SocketAsyncEventArgs saea = new System.Net.Sockets.SocketAsyncEventArgs();
            saea.Completed += SocketAsyncEventArgs_SendCompleted;
            saea.SetBuffer(bts, 0, bts.Length);
            saea.AcceptSocket = co.EventArgs.AcceptSocket;
            saea.UserToken    = co.EventArgs.UserToken;
            co.EventArgs.AcceptSocket.SendAsync(saea);
            Debug.WriteLine(Req.Header.Method + " " + Req.Header.Path + " " + Res.Header.Code + " " + Res.Header.Status);
        }
Пример #2
0
            void RespondAppendEntriesAsLeader()
            {
                var request = this.ReceivedEvent as AppendEntriesResponse;

                if (request.Term > this.CurrentTerm)
                {
                    this.CurrentTerm = request.Term;
                    this.VotedFor    = null;

                    this.RedirectLastClientRequestToClusterManager();
                    this.Raise(new BecomeFollower());
                    return;
                }
                else if (request.Term != this.CurrentTerm)
                {
                    return;
                }

                if (request.Success)
                {
                    this.NextIndex[request.Server]  = this.Logs.Count + 1;
                    this.MatchIndex[request.Server] = this.Logs.Count;

                    this.VotesReceived++;
                    if (request.ReceiverEndpoint != null &&
                        this.VotesReceived >= (this.Servers.Length / 2) + 1)
                    {
                        var commitIndex = this.MatchIndex[request.Server];
                        if (commitIndex > this.CommitIndex &&
                            this.Logs[commitIndex - 1].Term == this.CurrentTerm)
                        {
                            this.CommitIndex = commitIndex;
                        }

                        this.VotesReceived     = 0;
                        this.LastClientRequest = null;

                        this.Send(request.ReceiverEndpoint, new Client.Response());
                    }
                }
                else
                {
                    if (this.NextIndex[request.Server] > 1)
                    {
                        this.NextIndex[request.Server] = this.NextIndex[request.Server] - 1;
                    }

                    var logs = this.Logs.GetRange(this.NextIndex[request.Server] - 1,
                                                  this.Logs.Count - (this.NextIndex[request.Server] - 1));

                    var prevLogIndex = this.NextIndex[request.Server] - 1;
                    var prevLogTerm  = this.GetLogTermForIndex(prevLogIndex);

                    this.Send(request.Server, new AppendEntriesRequest(this.CurrentTerm, this.Id, prevLogIndex,
                                                                       prevLogTerm, logs, this.CommitIndex, request.ReceiverEndpoint));
                }
            }
Пример #3
0
            void ProcessClientRequest()
            {
                this.LastClientRequest = this.ReceivedEvent as Client.Request;

                var log = new Log(this.CurrentTerm, this.LastClientRequest.Command);

                this.Logs.Add(log);

                this.BroadcastLastClientRequest();
            }
Пример #4
0
            private void ProcessClientRequest(Event e)
            {
                this.LastClientRequest = e as Client.Request;

                var log = new Log(this.CurrentTerm, this.LastClientRequest.Command);

                this.Logs.Add(log);

                this.BroadcastLastClientRequest();
            }
Пример #5
0
        virtual public Response HandleRequest(Client.Request Req)
        {
            Response Res = new Response()
            {
                Header = new ResponseHeader()
                {
                    Code     = 200,
                    Status   = "OK",
                    Protocol = Req.Header.Protocol
                }
            };

            Res.Header["Server"]       = "WPServer";
            Res.Header["Content-Type"] = "text/html";

            Context cxt = new Context()
            {
                Request  = Req,
                Response = Res
            };


            PathHandlerItem phi = GetHandler(Req.Header.Path);

            if (phi != null)
            {
                if (phi.PathReg != null)
                {
                    cxt.PathArgs = new List <string>();
                    Match m = phi.PathReg.Match(Req.Path);
                    if (m.Success)
                    {
                        foreach (Group g in m.Groups)
                        {
                            cxt.PathArgs.Add(g.Value);
                        }
                    }
                }
                try
                {
                    System.Reflection.MethodInfo mi = phi.Handler.GetType().GetMethod(Req.Method);
                    if (mi != null)
                    {
                        mi.Invoke(phi.Handler, new object[] { cxt });
                    }
                    else if (phi.Handler.handler != null)
                    {
                        //
                        phi.Handler.handler(cxt);
                    }
                    else
                    {
                        throw new Exception(String.Format("No handler for {0} {1}", Req.Method, Req.Path));
                    }
                }
                catch (Exception e)
                {
                    Res.ResponseError(500, "Server Error", String.Format("<html><header><title>Server Error</title></header><body><pre>{0}</pre></body></html>", e.Message + "\r\n" + e.StackTrace));
                }
            }
            else
            {
                Res.ResponseError(404, "Not Found");
            }
            return(cxt.Response);
        }
Пример #6
0
        void SocketAsyncEventArgs_ReceiveCompleted(object sender, System.Net.Sockets.SocketAsyncEventArgs e)
        {
            String key = e.UserToken as String;

            if (e.Buffer != null && e.AcceptSocket != null && e.AcceptSocket.Connected && e.AcceptSocket.RemoteEndPoint != null)
            {
                try
                {
                    if (e.BytesTransferred > 0)
                    {
                        Socket       soc = e.AcceptSocket;
                        ClientObject co  = null;
                        if (Clients.ContainsKey(key))
                        {
                            co = Clients[key];
                        }
                        else
                        {
                            co = new ClientObject()
                            {
                                EventArgs = e
                            };
                            Clients[key] = co;
                        }
                        if (e.LastOperation == SocketAsyncOperation.Receive)
                        {
                            //Debug.WriteLine(key + " R:" + e.BytesTransferred);

                            switch (co.Status)
                            {
                            case ClientStatus.WaitHeader:
                            {
                                int           start = Math.Max(0, co.Buffer.Count - Base.DoubleNewLineBytes.Length - 1);
                                StringBuilder sb    = new StringBuilder();
                                for (int i = 0; i < e.BytesTransferred; ++i)
                                {
                                    //sb.Append(String.Format("{0} ", e.Buffer[e.Offset + i]));
                                    co.Buffer.Add(e.Buffer[e.Offset + i]);
                                }
                                //Debug.WriteLine(sb);
                                int ix = co.Buffer.IndexOfBytes(Base.DoubleNewLineBytes, start);
                                if (ix > 0)
                                {
                                    int    nstart = ix + Base.DoubleNewLineBytes.Length;
                                    byte[] bytes  = co.Buffer.ToArray();
                                    co.Buffer.Clear();

                                    for (int i = nstart; i < bytes.Length; ++i)
                                    {
                                        co.Buffer.Add(bytes[i]);
                                    }

                                    Client.RequestHeader Header = new Client.RequestHeader(Encoding.UTF8.GetString(bytes, 0, nstart));
                                    co.Header = Header;
                                    co.Status = co.Buffer.Count < co.Header.ContentLength ? ClientStatus.WaitBody : ClientStatus.Completed;
                                }
                                break;
                            }

                            case ClientStatus.WaitBody:
                            {
                                for (int i = 0; i < e.BytesTransferred; ++i)
                                {
                                    co.Buffer.Add(e.Buffer[e.Offset + i]);
                                }
                                if (co.Buffer.Count >= co.Header.ContentLength)
                                {
                                    co.Status = ClientStatus.Completed;
                                }
                                break;
                            }
                            }

                            if (co.Status == ClientStatus.Completed)
                            {
                                //
                                Client.Request Req = new Client.Request()
                                {
                                    Header = co.Header,
                                };
                                ProcessRequest(co);
                                co.Header = null;
                                co.Status = ClientStatus.WaitHeader;
                                co.Buffer.Clear();
                            }
                            soc.ReceiveAsync(co.EventArgs);
                        }
                    }
                    else
                    {
                        // closed
                        Debug.WriteLine(key + ":" + "Close");
                        Clients.Remove(key);
                    }
                }
                catch
                {
                    Clients.Remove(key);
                }
            }
        }
Пример #7
0
            void RespondAppendEntriesAsLeader(Event e)
            {
                var request = e as AppendEntriesResponse;

                if (request.Term > this.CurrentTerm)
                {
                    this.CurrentTerm = request.Term;
                    this.VotedFor    = null;

                    this.RedirectLastClientRequestToClusterManager();
                    this.RaiseEvent(new BecomeFollower());
                    return;
                }
                else if (request.Term != this.CurrentTerm)
                {
                    return;
                }

                if (request.Success)
                {
                    this.NextIndex[request.Server]  = this.Logs.Count + 1;
                    this.MatchIndex[request.Server] = this.Logs.Count;

                    this.VotesReceived++;
                    if (request.ReceiverEndpoint != null &&
                        this.VotesReceived >= (this.Servers.Length / 2) + 1)
                    {
                        this.Logger.WriteLine("\n [Leader] " + this.ServerId + " | term " + this.CurrentTerm +
                                              " | append votes " + this.VotesReceived + " | append success\n");

                        var commitIndex = this.MatchIndex[request.Server];
                        if (commitIndex > this.CommitIndex &&
                            this.Logs[commitIndex - 1].Term == this.CurrentTerm)
                        {
                            this.CommitIndex = commitIndex;

                            this.Logger.WriteLine("\n [Leader] " + this.ServerId + " | term " + this.CurrentTerm +
                                                  " | log " + this.Logs.Count + " | command " + this.Logs[commitIndex - 1].Command + "\n");
                        }

                        this.VotesReceived     = 0;
                        this.LastClientRequest = null;

                        this.SendEvent(request.ReceiverEndpoint, new Client.Response());
                    }
                }
                else
                {
                    if (this.NextIndex[request.Server] > 1)
                    {
                        this.NextIndex[request.Server] = this.NextIndex[request.Server] - 1;
                    }

                    var logs = this.Logs.GetRange(this.NextIndex[request.Server] - 1,
                                                  this.Logs.Count - (this.NextIndex[request.Server] - 1));

                    var prevLogIndex = this.NextIndex[request.Server] - 1;
                    var prevLogTerm  = this.GetLogTermForIndex(prevLogIndex);

                    this.Logger.WriteLine("\n [Leader] " + this.ServerId + " | term " + this.CurrentTerm + " | log " +
                                          this.Logs.Count + " | append votes " + this.VotesReceived +
                                          " | append fail (next idx = " + this.NextIndex[request.Server] + ")\n");

                    this.SendEvent(request.Server, new AppendEntriesRequest(this.CurrentTerm, this.Id, prevLogIndex,
                                                                            prevLogTerm, logs, this.CommitIndex, request.ReceiverEndpoint));
                }
            }