public ActionResult Command(String deviceId, int timeout = 60)
        {
            EventWaitHandle waitHandle;

            using (mongoContext = Context.MongoDBContext.MongoContextFactory.GetContext())
            using (rabbitContext = Context.RabbitMqContext.RabbitMqContextFactory.GetContext())
            {
                JObject command = rabbitContext.GetCommand(deviceId);
                if (command == null)
                {

                    //загрузка ЦП на самом деле не меняется абсолютно
                    waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);

                    NewCommandSignal sign = delegate(String devId)
                    {
                        if (deviceId == devId)
                        {
                            command = rabbitContext.GetCommand(deviceId);
                            waitHandle.Set();
                        }
                    };

                //на момент написания этого кода у меня похоже недостаточно опыта в WCF чтобы элегантно реализвать long polling
                // в асинхронном виде. да еще встроить в ASP.net контроллер. есть в документации аттрбут AsyncPattern для контракта. если удасться, к понедельнику переделаю
                //c использованием WCF. хотя что-то мне подсказывает, что я должен был сделать не на ASP.net при использовании WCF, а просто на WCF

                    onNewCommand += sign;

                    waitHandle.WaitOne((Int32)timeout * 1000);

                    onNewCommand -= sign;

                    if (onRequestProcessed != null)
                        onRequestProcessed.Invoke(command);
                    if (command != null)
                    {
                        return Json((Models.DSRCommand)command.ToObject(typeof(Models.DSRCommand)), JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json(null, JsonRequestBehavior.AllowGet);
                    }
                }
                else
                {
                    String js = command.ToString();
                    if (onRequestProcessed != null)
                        onRequestProcessed.Invoke(command);

                    return Json((Models.DSRCommand)command.ToObject(typeof(Models.DSRCommand)), JsonRequestBehavior.AllowGet);
                }
            }
        }
        public ViewResult LogView(Models.ViewContext context)
        {
            mongoContext = Context.MongoDBContext.MongoContextFactory.GetContext();
            List<JObject> history = mongoContext.GetHistory(context.deviceIdForLogRequest);
            context.history = new List<Models.DSRCommand>();

            foreach (JObject historyItem in history)
            {
                Models.DSRCommand historyCommand = (Models.DSRCommand)historyItem.ToObject(typeof(Models.DSRCommand));
                context.history.Add(historyCommand);
            }
            return View("LogView", context);
        }
        public void NewCommand()
        {
            using (mongoContext = Context.MongoDBContext.MongoContextFactory.GetContext())
            using (rabbitContext = Context.RabbitMqContext.RabbitMqContextFactory.GetContext())
            {
                bool valid = true;
                Byte[] body = new Byte[Request.InputStream.Length];
                Request.InputStream.Position = 0;
                Request.InputStream.Read(body, 0, body.Length);
                JObject newCommand = JObject.Parse(Encoding.UTF8.GetString(body));

                Models.DSRCommand newDsrCommand = (Models.DSRCommand)newCommand.ToObject(typeof(Models.DSRCommand));

                if (newDsrCommand.command.parameters != null)
                {
                    foreach (Models.DSRCommand.Command.Parameter paramter in newDsrCommand.command.parameters)
                    {
                        if (paramter.name == null || paramter.value == null || paramter.name == "")
                            valid = false;
                    }
                }
                else
                    valid = false;

                if (
                    valid == false ||
                    newDsrCommand.deviceId == null ||
                    newDsrCommand.command.commandName == null || Enum.GetNames(typeof(Models.DSRCommand.CommandList)).Contains<String>(newDsrCommand.command.commandName) == false ||
                    newDsrCommand.command.parameters == null)
                {
                    Response.StatusCode = 406;
                    Response.Clear();
                    Response.Flush();
                    return;
                }

                rabbitContext.NewCommand(newCommand);

                mongoContext.NewCommand(newCommand);

                if (onNewCommand != null)
                    onNewCommand.Invoke(newCommand.GetValue("deviceId").ToString());

                Response.Clear();
                Response.Flush();
            }
        }
        public ActionResult Command(String deviceId, int timeout = 60)
        {
            rabbitContext = Context.RabbitMqContext.RabbitMqContextFactory.GetContext();
            JObject command = rabbitContext.GetCommand(deviceId);
            if (command == null)
            {
                bool polling = true;
                Timer pollingTimer = null;

                pollingTimer = new System.Threading.Timer(delegate(Object state)
                {
                    if (pollingTimer != null)
                    {
                        pollingTimer.Change(-1, Timeout.Infinite);
                        pollingTimer.Dispose();
                        pollingTimer = null;
                        polling = false;
                    }
                }, null, (Int32)timeout * 1000, timeout * 1000);

                NewCommandSignal sign = delegate(String devId)
                {
                    if (deviceId == devId)
                    {
                        pollingTimer.Change(-1, Timeout.Infinite);
                        pollingTimer.Dispose();
                        pollingTimer = null;

                        command = rabbitContext.GetCommand(deviceId);
                        polling = false;
                    }
                };

                onNewCommand += sign;

                //на момент написания этого кода у меня похоже недостаточно опыта в WCF чтобы элегантно реализвать long polling
                // в асинхронном виде. есть в документации аттрбут AsyncPattern для контракта. если удасться, к понедельнику переделаю
                //c использованием WCF

                while (polling)
                    Thread.Sleep(10);

                onNewCommand -= sign;

                if (onRequestProcessed != null)
                    onRequestProcessed.Invoke(command);

                Context.RabbitMqContext.RabbitMqContextFactory.CloseContext((Context.RabbitMqContext)rabbitContext);

                if (command != null)
                {
                    return Json((Models.DSRCommand)command.ToObject(typeof(Models.DSRCommand)), JsonRequestBehavior.AllowGet);
                }
                else
                {
                    return Json(null, JsonRequestBehavior.AllowGet);
                }
            }
            else
            {
                String js = command.ToString();
                if (onRequestProcessed!=null)
                    onRequestProcessed.Invoke(command);

                Context.RabbitMqContext.RabbitMqContextFactory.CloseContext((Context.RabbitMqContext)rabbitContext);
                return Json((Models.DSRCommand)command.ToObject(typeof(Models.DSRCommand)), JsonRequestBehavior.AllowGet);
            }
        }