Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Развертка HTTP сервера в Java SE |
Автор: Platon 6.9.2008, 09:12 | ||||||||||||||||||||||
Здравствтвуйте, уважаемые. В очередной раз хочу принести пользу обществу и поделиться своей сегодняшней находкой: HTTP сервер на базе пакета от нашего Солнышка com.sun.net.httpserver Введение. Чем может не устраивать развертка веб-контейнеров, таких как Apache Tomcat? В первую очередь, они достаточно увесистые. Они расчитаны на обширный круг задач, навязывая многие дополнительные возможности, в общем созданы для полноценных веб-приложений. Часто у нас возникает потребность в небольших HTTP серверах. К примеру, у нас имеется система, которая поддерживает 2 типа соединений: постоянные и HTTP запросы. Постоянные соединения - самая важная часть, лишь изредка необходимо запрашивать HTTP страницы (http://vingrad.ru/blogs/COVD/2008/03/12/potok-dannyih-i-zapros-otvet-odno-ili-neskolko-soedineniy/ для размышления). Это не веб приложение, и полнофункциональный веб-сервер нам ни к чему. И как раз HttpServer - небольшой пакет классов для поднятия простого Embedded HTTP сервера. Самое приятное, что их можно найти в SDK6. JavaDoc и краткое руководство на английском языке есть http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/package-summary.html Основная часть Задача: вывести на страницу список заголовков, отправляемых браузером в кодировке UTF-8. Запрос к серверу http://localhost:8080/path/to/data.make По традиции сразу выгружаю весь код
Вооружаемся секундомерами.
Несложно догадаться что мы создаем HTTP сервер, который слушает порт 8080. 2-й параметр я не очень понял.
Такое ощущение, что это локальный адрес соединения... Хорошо, что есть возможность дать на откуп программе установку этого параметра, поставив неположительное значение. Привязываем строки запросов с обработчиками
1-я строка связывает путь на сервере с обработчику. Иными словами, если будет запрошен заданный путь, то будет вызван привязанный к нему обработчик запроса HttpHandler. Интерфейс HttpHandler содержит всего 1 метод для определения, handle(HttpExchange httpExchange). Займемся этим. Класс HttpExchange содержит 6 важных методов, которые хорошо расписаны в документации:
По порядку 1. Оборачиваем OutputStream ответа в поток с кодировкой UTF-8. 2. Пробуем поэксперементировать с заголовками ответа (тип документа и его кодировка) 3. отправляем ответы клиенту 200 (страница найдена) и неизвестную длину посылки. 4. Отдельного разговора заслуживает метод httpExchange.getRequestURI() в качестве теста, можете набрать в браузере строку типа "/path/to/data.make?arg1=12&arg2=name" Мы видим, что несмотря на то, что строка запроса уже не совпадает с /path/to/data.make тем не менее HttpServer может отделать часть запроса от передаваемых параметров и вызвать обработчик, привязанный к пути /path/to/data.make 5-9. отправляем полученные заголовки запроса обратно, но уже в теле ответа, а не в виде заголовков 10. Проверяем работает ли установленная нами кодировка, выводя русский текст. 11. Обязательно(!) закрываем поток ответа. Работа с фильтрами
Схема довольно проста. HttpContext, который мы создали на прошлом шаге, может быть предварительно и после обработан фильтрами. Фильтры вызываются в порядке добовления их в цепь фильтров, получаемую методом c.getFilters(). Filter#description() - краткое описание фильтра. Методы обработки одновременных запросов
Закоментированная строка имеет место быть для супер простых серверов с небольшой степенью одновременных запросов. Executor по умолчанию обрабатывает по одной задаче в момент времени. Такой подход конечно же неприемлем в боевых условиях. На сколько я понял, выполняется что-то подобное.
Второй строкой я привел боевой пример. Несколько потоков-работников будут параллельно обрабатывать запросы клиентов. Вот жесткий тест на 1000 псевдоодновременных подключений:
Здесь могла бы быть ваша реклама http://platon007.blogspot.com/2008/08/blog-post.html |
Автор: COVD 6.9.2008, 15:22 |
Я пока осилил только Введение ( остальное потом дочитаю ). Но драгоценные мысли уже на Введении пришли в голову ![]() Embedded ... У нас, в начале, на сервере тоже все было в одном флаконе. Стоял Томкат, а под ним копошился собственно сервер. Сервер был "embedded" в Томкат, а не наоборот. Но не в этом суть. Нам Томкат был нужен в основном для http тунеллинга, т.е. для обслуживания на 80-го порту клиентов, защищенных файерволом. И тоже слегка смущало, что приходится возиться с Томкатом ради пары сервлетов. Но со временем обнаружилось, что приложения на сервере имеют тенденцию расползаться. То, что бегало в одном флаконе, стало проситься бегать на разных машинах, да еще и размножаться. А развод - дело хлопотное. Поэтому на сервере решениям "embedded" и "в одном флаконе" возможно лучше сразу предпочесть отдельные приложения. А для коммуникации между ними можно использовать, например, RMI, или наладить обмен асинхронными сообщениями через апачевский ActiveMQ |