private static async Task HandleUploadRequest(WebSocketSession session, dynamic request) { using (var ticket = q.EnterQueue()) { var getContext = ticket.GetContext(); var clientQuery = session.ReceiveTextMessage(); while (true) { var completed = await Task.WhenAny(getContext, clientQuery, Task.Delay(TimeSpan.FromSeconds(5))); if (completed == getContext) { await getContext; // possible future use // got context, upload starts await session.SendObject(new { Status = "ReadyForUpload" }); var uploadInfo = BsonDocument.Parse(await clientQuery.WithTimeout(ClientReadTimeout)); Overview overview; if (uploadInfo["Status"] == "CustomMap") { overview = BsonSerializer.Deserialize <Overview>(uploadInfo["Overview"].AsBsonDocument); } else if (uploadInfo["Status"] == "DefaultMap") { overview = null; } else { throw new NotImplementedException(); } Debug.WriteLine("omfg getting stream now"); var uploadStream = await session.ReceiveBinaryMessage(); Debug.WriteLine("SHIT SHIT SHIT GOT THE STREAM EVERYTHING IS AWESOME"); var demoFileName = Guid.NewGuid().ToString() + ".dem"; using (var dbStoreStream = File.Create(Path.Combine("demos", demoFileName))) using (var tee = new DoubleBufferedTeeStream(uploadStream, dbStoreStream)) { // upload to "db" (file system) WHILE PARSING :D var h = new Heatmap(Database, tee, overview); h.OnRoundAnalysisFinished += async(analysis) => { var doc = new BsonDocument(); doc["Status"] = "AnalysisProgress"; doc["Analysis"] = analysis.ToBsonDocument(); await session.SendTextMessage(doc.ToJson(MongoJsonSettings)); }; var ana = h.ParseHeaderOnly(); ana.DemoFile = demoFileName; Database.Save(ana); var asDoc = new BsonDocument(); asDoc["Status"] = "AnalysisStarted"; asDoc["Analysis"] = ana.ToBsonDocument(); await session.SendTextMessage(asDoc.ToJson(MongoJsonSettings)); h.ParseTheRest(); } await session.SendObject(new { Status = "UploadComplete" }); break; } else if (completed == clientQuery) { // client query? wat? (we don't expect this) // TODO: handle cancellation and stuff throw new System.IO.InvalidDataException("protocol violation"); } else { // still there. send them their current position. await session.SendObject(new { Status = "InQueue", QueuePosition = ticket.QueuePosition }); } } } }