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); }
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)); } }
void ProcessClientRequest() { this.LastClientRequest = this.ReceivedEvent as Client.Request; var log = new Log(this.CurrentTerm, this.LastClientRequest.Command); this.Logs.Add(log); this.BroadcastLastClientRequest(); }
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(); }
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); }
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); } } }
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)); } }