//вызов метода после полной обработки поступившего запроса. отправляет ответ и закрывает соединение public async void OnHttpResponce(HTTPRequest responce, ClientConnection client) { if (responce == null) { client.socket.Close(); clientList.Remove(client); return; } foreach (String header in responce.headers) await client.socket.GetStream().WriteAsync(Encoding.UTF8.GetBytes(header), 0, header.Length); await client.socket.GetStream().WriteAsync(Encoding.UTF8.GetBytes("\r\n"), 0, 2); if(responce.content != null) await client.socket.GetStream().WriteAsync(responce.content, 0, responce.content.Length); await client.socket.GetStream().WriteAsync(Encoding.UTF8.GetBytes("\r\n"), 0, 2); client.socket.Close(); clientList.Remove(client); }
async void ControllerRunMethod() { //RabbitMq Init var factory = new ConnectionFactory() { HostName = RabbitMQAddr }; try { using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { Console.WriteLine("[+] Connecting to RabbitMQ service at {0} OK", RabbitMQAddr); } } catch (Exception ex) { Console.WriteLine("[-] Connecting to RabbitMQ service at {0} failed!", RabbitMQAddr, ex.Message); } //Http SErve Init HTTPServer server = new HTTPServer(TCPListeningPort); //Mongo Init client = new MongoClient(MongoDbConnectionString); dataBase = client.GetDatabase("DSR_Commands"); var collection = dataBase.GetCollection<BsonDocument>("DSR_Commands"); var testCollection = dataBase.GetCollection<BsonDocument>("DBConnectionTest"); BsonDocument testCommand = new BsonDocument(); testCommand.Add("test", "test"); try { await testCollection.InsertOneAsync(testCommand); Console.WriteLine("[+] Connecting to MongoDB with ConnectionString {0} OK", MongoDbConnectionString); } catch (Exception) { Console.WriteLine("[-] Connecting to MongoDB with ConnectionString {0} FAILED", MongoDbConnectionString); } onResponceForClient += server.OnHttpResponce; server.OnNewHttpRequest += async delegate(HTTPRequest request, HTTPServer.ClientConnection clientConnection) { String[] substrings = request.headers[0].Split(new String[] { "/", " " }, StringSplitOptions.RemoveEmptyEntries); //запрос на получени веб-интерфеса, возврщаеи html файл if (substrings[0] == "GET" && substrings[1] == "HTTP") { Console.WriteLine("[+] Request Accepted. GET WebPAge Interface "); if (onResponceForClient != null) { HTTPRequest responce = new HTTPRequest(); String tr = Properties.Resources.WebInterface; Byte[] content = Encoding.UTF8.GetBytes(tr); String contentLenhthHeader = String.Format("Content-Length: {0}\r\n", content.Length); String[] headers = { "HTTP/1.1 200 OK\r\n", "Date: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Server: Apache\r\n", "X-Powered-By: PHP/5.2.4-2ubuntu5wm1\r\n", "Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Content-Language: ru\r\n", "Content-Type: text/html; charset=utf-8", contentLenhthHeader, "Connection: close\r\n"}; foreach (String header in headers) responce.headers.Add(header); responce.content = content; onResponceForClient.Invoke(responce, clientConnection); } } //POST запрос из веб-интерфеса на создание новой команды else if (substrings[0] == "POST" && substrings[1] == "newCommand") { String argumentString = Encoding.UTF8.GetString(request.content); Console.WriteLine("[+] Request Accepted. POST WebPAge Interface new Command"); JObject newCommand = JObject.Parse(argumentString); newCommand.Add("creationTime", DateTime.Now); newCommand.Add("timeout", 60); newCommand.Add("expired", false); newCommand.Add("delivered", false); Console.WriteLine("[+] Request Accepted. POST deviceId = {0}", newCommand.GetValue("deviceId")); Console.WriteLine(" Command Details :"); //Console.WriteLine(" name = {0} value = {1}", details.name, details.value); BsonDocument doc = BsonDocument.Parse(newCommand.ToString()); await collection.InsertOneAsync(doc); if (onNewCommand != null) onNewCommand.Invoke(new DSRCommand() { deviceId = newCommand.GetValue("deviceId").ToString() }); if (onResponceForClient != null) { HTTPRequest responce = new HTTPRequest(); String[] headers = { "HTTP/1.1 200 OK\r\n", "Date: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Server: Apache\r\n", "X-Powered-By: PHP/5.2.4-2ubuntu5wm1\r\n", "Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Content-Language: ru\r\n", "Content-Type: text/html; charset=utf-8", "Connection: close\r\n"}; foreach (String header in headers) responce.headers.Add(header); onResponceForClient.Invoke(responce, clientConnection); } } // запрос из веб-интерфеса лога команд для девайса else if (substrings[0] == "GET" && substrings[1].StartsWith("viewLog?devId=")) { String argumentString; if (true) { argumentString = substrings[1].Remove(0, "viewLog?devId=".Length); Console.WriteLine("[+] Request Accepted. POST View Log deviceId = {0} ", argumentString); var builder = Builders<BsonDocument>.Filter; var filter = builder.Eq("deviceId", argumentString); var cursor = await collection.FindAsync(filter); StringBuilder resultBuilder = new StringBuilder(); while (await cursor.MoveNextAsync()) { Object batch = cursor.Current; var enumerator = (batch as IEnumerable<BsonDocument>).GetEnumerator(); enumerator.Reset(); int count = 0; while (enumerator.MoveNext()) { BsonDocument command = enumerator.Current; command.Remove("_id"); command.Remove("expired"); if (resultBuilder.Length == 0) resultBuilder.Append("{\"log\":["); if(count != 0) resultBuilder.Append(","); resultBuilder.Append(command.ToJson().ToString()); count++; } if(count != 0) resultBuilder.Append("]}"); } Byte[] content = Encoding.UTF8.GetBytes(resultBuilder.ToString()); HTTPRequest responce = new HTTPRequest(); String contentLenhthHeader = String.Format("Content-Length: {0}\r\n", content.Length); String[] headers = { "HTTP/1.1 200 OK\r\n", "Date: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Server: Apache\r\n", "X-Powered-By: PHP/5.2.4-2ubuntu5wm1\r\n", "Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Content-Language: ru\r\n", "Content-Type: application/json;\r\n", contentLenhthHeader, "Connection: close\r\n"}; foreach (String header in headers) responce.headers.Add(header); String test = resultBuilder.ToString(); Object and = JsonConvert.DeserializeObject(test); responce.content = content; onResponceForClient.Invoke(responce, clientConnection); } } // запрос от клиентского девайса команды else if (substrings[0] == "GET" && substrings[1] == "command") { Console.WriteLine("[+] Request Accepted. GET deviceId = {0} timeout = {1} ", substrings[2], substrings[3]); var builder = Builders<BsonDocument>.Filter; var filter = builder.Eq("deviceId", substrings[2]) & builder.Eq("expired", false) & builder.Eq("delivered", false);// &builder.Gte("creationTime", DateTime.Now.AddSeconds(-60000)); var update = Builders<BsonDocument>.Update; var updater = update.Set("delivered", true); bool polling = true; bool checkCollection = true; Timer pollingTimer = null; int timeout = 10000; if (!int.TryParse(substrings[3], out timeout)) timeout = 60000; else timeout *= 1000; pollingTimer = new System.Threading.Timer(delegate(Object state) { if (pollingTimer != null) { pollingTimer.Change(-1, Timeout.Infinite); pollingTimer.Dispose(); pollingTimer = null; polling = false; onResponceForClient.Invoke(null, clientConnection); } }, null, (Int32)timeout, timeout); while (polling) { if (checkCollection == false) continue; var cursor = await collection.FindAsync(filter); if(await cursor.MoveNextAsync()) { Object batch = cursor.Current; var enumerator = (batch as IEnumerable<BsonDocument>).GetEnumerator(); enumerator.Reset(); if (enumerator.MoveNext()) { if (onResponceForClient != null) { HTTPRequest responce = new HTTPRequest(); BsonDocument command = enumerator.Current; BsonDocument details = command.GetValue("command").AsBsonDocument; command.Remove("_id"); command.Remove("expired"); command.Remove("creationTime"); command.Remove("delivered"); command.Remove("timeout"); Byte[] content = Encoding.UTF8.GetBytes(command.ToJson().ToString()); String contentLenhthHeader = String.Format("Content-Length: {0}\r\n", content.Length); String[] headers = { "HTTP/1.1 200 OK\r\n", "Date: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Server: Apache\r\n", "X-Powered-By: PHP/5.2.4-2ubuntu5wm1\r\n", "Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT\r\n", "Content-Language: ru\r\n", "Content-Type: application/json;\r\n", contentLenhthHeader, "Connection: close\r\n"}; foreach (String header in headers) responce.headers.Add(header); responce.content = content; onResponceForClient.Invoke(responce, clientConnection); await collection.UpdateOneAsync(filter, updater); polling = false; pollingTimer.Change(-1, Timeout.Infinite); pollingTimer.Dispose(); pollingTimer = null; } } else { //начало long polling onNewCommand += delegate(DSRCommand command) { if (command.deviceId == substrings[2]) // Captain ? :) { checkCollection = true; //check collection once } }; } } checkCollection = false; } } // POST запрос от клиента с новой командой else if (substrings[0] == "POST") { String contentString = Encoding.UTF8.GetString(request.content); JObject newCommand = JObject.Parse(contentString); newCommand.Add("creationTime", DateTime.Now); newCommand.Add("timeout", 60); newCommand.Add("expired", false); newCommand.Add("delivered", false); Console.WriteLine("[+] Request Accepted. POST deviceId = {0}", newCommand.GetValue("deviceId")); Console.WriteLine(" Command Details :"); Console.WriteLine(" deviceID : {0}", newCommand.GetValue("command")); //Console.WriteLine(" name = {0} value = {1}", details.name, details.value); BsonDocument doc = BsonDocument.Parse(newCommand.ToString()); await collection.InsertOneAsync(doc); if (onNewCommand != null) onNewCommand.Invoke(new DSRCommand() { deviceId = newCommand.GetValue("deviceId").ToString() }); } }; while (true) { Thread.Sleep(100); String command = Console.ReadLine(); switch (command) { case "get": { using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.QueueDeclare("hello", false, false, false, null); var consumer = new QueueingBasicConsumer(channel); channel.BasicConsume("hello", true, consumer); var ea = new BasicDeliverEventArgs(); if (consumer.Queue.Dequeue(1000, out ea)) { var body = ea.Body; BinaryFormatter formatter = new BinaryFormatter(); Stream stream = new MemoryStream(ea.Body); DSRCommand gotCommand = (DSRCommand)formatter.Deserialize(stream); stream.Read(body, 0, (int)stream.Length); } } } break; } } } }