HttpListener для простого Http-сервера в производстве - PullRequest
1 голос
/ 17 февраля 2012

Я реализовал действительно простой C # Http-сервер, используя HttpListener в рамках службы Windows, которая ожидает запросы и отправляет их ZMQ при получении. Здесь он очень похож на HTTP-сервер - Готовый к работе многопоточный сервер c # http , за исключением того, что он выполняет делегат RunServer асинхронно, а затем, когда служба запущена, находится в непрерывном цикле, который прослушивает HttpListener. Я думаю, что у меня есть кое-что, что работает в большинстве случаев, однако, когда я останавливаю сервер, если запросы не выполнены, он выдает ошибку

Операция ввода-вывода была прервана из-за выхода из потока или запрос заявки

в методе Handle. Я волнуюсь, я пропускаю другие вещи, которые были бы необходимы для производственной среды.

    public XsmHttpServer(string httpAddressEndpoint)
    {                        
        _listener = new HttpListener();
        _listenerAddr = httpAddressEndpoint;
    }

    public void Start()
    {
        _listener.Start();

        Action action = RunServer;
        action.BeginInvoke(RunServerCallback, action);                        
    }


    private void RunServer()
    {
        while (_listener.IsListening)
        {
            IAsyncResult result = _listener.BeginGetContext(Handle, _listener);
            result.AsyncWaitHandle.WaitOne();
        }
    }


    private void Handle(IAsyncResult result)
    {
        HttpListener listener = (HttpListener)result.AsyncState;
        HttpListenerContext context = listener.EndGetContext(result);

        //Do work, send to ZMQ & write response back 
        _handler.Handle(context);                                         
    }

    private void RunServerCallback(IAsyncResult ar)
    {
        try
        {
            Action target = (Action)ar.AsyncState;
            target.EndInvoke(ar);
        }
        catch (Exception ex)
        {
            if (_log.IsDebugEnabled) _log.Debug("Failed to initialize Server", ex);  
        }
    }


    public void Stop()
    {
       _listener.Close();
    }

1 Ответ

3 голосов
/ 20 февраля 2012

Под "остановкой сервера" я предполагаю, что вы имеете в виду, что вызываете метод Stop () в своем коде. Это вызывает метод Close () слушателя, который не может завершить все ожидающие запросы (http://msdn.microsoft.com/en-us/library/system.net.httplistener.close.aspx).

).

Вы должны сначала вызвать метод Stop () слушателя, дождаться обработки всех ожидающих запросов, а затем закрыть его ().

Если ваше приложение не разрешает отсеивать эти ожидающие запросы, в этом случае вы можете просто принять и игнорировать ошибку, но, в общем, было бы лучше, чтобы они закончили, чтобы избежать ситуаций, когда вы наполовину обработал запрос, и клиент повторно отправил его.

...