/// <summary> /// Add a log entry for when the model is updated. /// </summary> /// <param name="first">The old sequence number.</param> /// <param name="second">The new sequence number.</param> /// <param name="data">The model diff data.</param> private void LogModelDiff(int first, int second, String data) { // Log the model update to file so that we can calculate performance metrics later. // NOTE: Log format is: <SERVER_TIME>, <CLIENT>, <TYPE>, <START_SEQ>, <END_SEQ>, <DATA> StringBuilder logEntry = new StringBuilder(); logEntry.Append(WebService.ToUnixTime(System.DateTime.Now).ToString()); logEntry.Append(","); logEntry.Append(0); logEntry.Append(","); logEntry.Append("'MODEL_DIFF'"); logEntry.Append(","); logEntry.Append(first); logEntry.Append(","); logEntry.Append(second); logEntry.Append(","); logEntry.Append("'"); logEntry.Append(data); logEntry.Append("'"); if (sw != null) { lock (sw) { sw.WriteLine(logEntry.ToString()); } } }
/// <summary> /// Add a log entry for when we send a pong back to a client. /// </summary> /// <param name="client">The id of the client.</param> /// <param name="data">The response data.</param> private void LogPong(int client, String data) { // Log the model update to file so that we can calculate performance metrics later. // NOTE: Log format is: <SERVER_TIME>, <CLIENT>, <TYPE>, <START_SEQ>, <END_SEQ>, <DATA> StringBuilder logEntry = new StringBuilder(); logEntry.Append(WebService.ToUnixTime(System.DateTime.Now).ToString()); logEntry.Append(","); logEntry.Append(client); logEntry.Append(","); logEntry.Append("'PONG'"); logEntry.Append(","); logEntry.Append(-1); logEntry.Append(","); logEntry.Append(-1); logEntry.Append(","); logEntry.Append("'"); logEntry.Append(data); logEntry.Append("'"); if (sw != null) { lock (sw) { sw.WriteLine(logEntry.ToString()); } } }
/// <summary> /// Add a log entry for when we receive a submission from clients. /// </summary> /// <param name="client">The id of the client.</param> /// <param name="deck">The deck index.</param> /// <param name="slide">The slide index.</param> private void LogSubmissionReceived(int client, int deck, int slide) { // NOTE: Log format is: <SERVER_TIME>, <CLIENT>, <DECK_INDEX>, <SLIDE_INDEX> StringBuilder logEntry = new StringBuilder(); logEntry.Append(WebService.ToUnixTime(System.DateTime.Now).ToString()); logEntry.Append(","); logEntry.Append(client); logEntry.Append(","); logEntry.Append("'SUBMISSION'"); logEntry.Append(","); logEntry.Append(deck); logEntry.Append(","); logEntry.Append(slide); if (sw != null) { lock (sw) { sw.WriteLine(logEntry.ToString()); } } }
/// <summary> /// Handle data posted to up by th web client. /// </summary> /// <param name="parameters">The query string parameters.</param> /// <param name="postData">The post data string.</param> /// <returns>The response text.</returns> private string PostHandler(NameValueCollection parameters, string postData) { // Get the parts of the post data. string[] items = postData.Split(new char[] { '|' }); if (items[0] == STUDENT_SUBMISSION_REQUEST) // Handle student submission. // Deserialize the Array of SimpleStrokeModel from the post data. { int clientId = Convert.ToInt32(items[1]); int deck = Convert.ToInt32(items[2]); int slide = Convert.ToInt32(items[3]); object strokes = JSON.Decode(items[4]); if (strokes is List <object> ) { ArrayList deserializedStrokes = new ArrayList(); List <object> strokesArray = (List <object>)strokes; foreach (object stroke in strokesArray) { if (stroke is List <KeyValuePair <string, object> > ) { SimpleWebInk deserializedStroke = new SimpleWebInk(); List <KeyValuePair <string, object> > strokeObject = (List <KeyValuePair <string, object> >)stroke; foreach (KeyValuePair <string, object> field in strokeObject) { switch (field.Key) { case "c": // Color if (field.Value is List <KeyValuePair <string, object> > ) { List <KeyValuePair <string, object> > color = (List <KeyValuePair <string, object> >)field.Value; foreach (KeyValuePair <string, object> channel in color) { if (channel.Key == "r") { deserializedStroke.R = (byte)Math.Round((double)channel.Value); } else if (channel.Key == "g") { deserializedStroke.G = (byte)Math.Round((double)channel.Value); } else if (channel.Key == "b") { deserializedStroke.B = (byte)Math.Round((double)channel.Value); } } } break; case "w": // Width if (field.Value is double) { deserializedStroke.Width = (float)((double)field.Value); } break; case "o": // Opacity if (field.Value is double) { deserializedStroke.Opacity = (byte)Math.Round((double)field.Value); } break; case "k": // Points if (field.Value is List <object> ) { List <object> points = (List <object>)field.Value; int numPoints = points.Count / 2; System.Drawing.Point[] pts = new System.Drawing.Point[numPoints]; for (int i = 0; i < numPoints; i++) { pts[i].X = (int)((double)points[(i * 2)] * 26.37f); pts[i].Y = (int)((double)points[(i * 2) + 1] * 26.37f); } deserializedStroke.Pts = pts; } break; } } deserializedStrokes.Add(deserializedStroke); } } // Notify listeners that a student submission was received. WebService.Instance.SubmissionReceived(WebServer.Instance, deck, slide, deserializedStrokes); } // Log that we responded to a pong. this.LogSubmissionReceived(clientId, deck, slide); } else if (items[0] == QUICK_POLL_REQUEST) // Handle quick poll. // Notify listeners that a quick poll update was received. { WebService.Instance.QuickPollReceived(WebServer.Instance, new Guid(items[1]), items[2]); } else if (items[0] == PING_REQUEST) // Handle ping request. { String clientId = items[1]; String clientTimestamp = items[2]; String serverTimestamp = WebService.ToUnixTime(System.DateTime.Now).ToString(); // We should respond with the current timestamp. String pong = "{\"u\":" + clientId + ",\"c\":" + clientTimestamp + ",\"s\":" + serverTimestamp + "}"; // Log that we responded to a pong. this.LogPong(Convert.ToInt32(clientId), pong); return(pong); } else if (items[0] == LOG_DUMP_REQUEST) // Handle a client log dump. { String clientId = items[1]; String logDump = items[2]; // Print the dumped log to a file. StreamWriter logFile = new StreamWriter( System.IO.Path.Combine(System.IO.Path.GetTempPath(), "CP_ClientPerformanceLog_" + clientId.ToString() + ".txt")); logFile.Write(logDump); logFile.Close(); } // By default, return an empty json object. return("{}"); }