что такое сервлет контейнер

Введение в сервлеты и контейнеры сервлетов

Изучите концепции, связанные с сервлетами, их контейнерами и несколькими основными объектами, вокруг которых они вращаются.

1. Обзор

Мы также увидим их в контексте запроса, ответа, объектов сеанса, общих переменных и многопоточности.

2. Что такое Сервлеты и их Контейнеры

Однако здесь важную роль играет параметр servlet load-on-startup . Если этот параметр имеет значение больше нуля, только тогда, когда сервер инициализирует его при запуске. Если этот параметр не указан, то init() сервлета вызывается, когда запрос попадает в него в первый раз.

3. Запрос, Ответ и сеанс

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

Помимо информации о методе, объект запроса также содержит другую информацию, такую как заголовки, параметры и тело. Аналогично, объект HttpServletResponse также содержит заголовки, параметры и тело – мы можем настроить их в методе doXXX нашего сервлета.

Как бы мы тогда поддерживали состояние между последующими клиентскими запросами или подключениями? HttpSession является ответом на эту загадку.

Это в основном привязывает объекты к сеансу пользователя, так что информация, относящаяся к конкретному пользователю, может сохраняться в нескольких запросах. Обычно это достигается с помощью концепции файлов cookie, используя JSESSIONID в качестве уникального идентификатора для данного сеанса. Мы можем указать тайм-аут для сеанса в web.xml :

Это означает, что если ваш сеанс простаивал в течение 10 минут, сервер откажется от него. Любой последующий запрос приведет к созданию нового сеанса.

4. Как Сервлеты Обмениваются Данными

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

Как мы видели в предыдущих разделах, разные объекты имеют разное время жизни. HttpServletRequest и HttpServletResponse объекты живут только между одним вызовом сервлета. HttpSession живет до тех пор, пока он активен и не истекло время ожидания.

Срок службы ServletContext самый длинный. Он рождается вместе с веб-приложением и уничтожается только тогда, когда само приложение завершает работу. Поскольку экземпляры сервлета, фильтра и прослушивателя привязаны к контексту, они также живут до тех пор, пока веб-приложение работает и работает.

Наконец, есть область запроса, относящаяся к данным для одного запроса, например полезная нагрузка запроса.

5. Обработка многопоточности

Несколько Объекты HttpServletRequest совместно используют сервлеты друг с другом, так что каждый запрос работает со своим собственным потоком экземпляра сервлета.

Например, давайте рассмотрим этот фрагмент:

6. Заключение

В этом уроке мы рассмотрели некоторые концепции, связанные с сервлетами, их контейнерами и несколькими важными объектами, вокруг которых они вращаются|/. Мы также видели, как сервлеты обмениваются данными и как многопоточность влияет на них.

Источник

Часть 5. Сервлеты, Java servlet API. Пишем простое веб-приложение

Что такое сервлет

Что нужно для создания веб-приложения

Создаем первое веб-приложение

В pom.xml добавим зависимость javax.servlet-api и установим packaging war:

Класс простого сервлета:

Для запуска приложения нужно создать Tomcat-конфигурацию:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнерчто такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Далее указываем, какую версию Tomcat мы будем использовать, URL, по которому можно обращаться к серверу и порт. У тебя должно получиться примерно так:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Осталось указать артефакт (собранный проект в jar-архив), который развернется в контейнере. Можно нажать кнопку Fix и выбрать war exploded : это значит, что после пересборки проекта артефакт будет автоматически помещаться в контейнер сервлетов. что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Зачем нам лишний текст? Удалим ненужное. Теперь адрес приложения у нас такой: http://localhost:8080.

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Нажимаем ОК. Видим, что у нас появилась возможность запуска приложения:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Обращаемся к нему по адресу http://localhost:8080/hello, и получаем ожидаемый ответ — строку “Hello”!

Источник

Часть 6. Контейнеры сервлетов

Содержание:

Что такое контейнер сервлетов

Как используют контейнеры сервлетов

Установка и запуск Tomcat

Для установки Tomcat просто распакуй скачанный архив в нужную директорию.

Учти, что для запуска и работы Tomcat нужна Java версии 8 или выше. Убедись, что переменная среды JAVA_HOME ссылается на актуальную версию jdk.

В Tomcat заранее предусмотрены четыре роли:

Внутри тега явно пропишем эти роли и назначим их нашему юзеру:

Теперь все готово к запуску!

В папке bin запусти файл startup.bat (startup.sh на Linux).

Через несколько секунд в браузере открой ссылку http://localhost:8080/. Там появится графический менеджер:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Если видишь такое меню, значит, Tomcat запущен.

Если не работает, вручную проверь переменные среды JAVA_HOME и CATALINA_HOME:

Развертывание приложения в Tomcat

С помощью графического интерфейса

Для этого переходим по ссылке http://localhost:8080/manager/html. Tomcat должен запросить логин и пароль.

После успешной авторизации ты увидишь Tomcat Web Application Manager. В разделе Applications уже содержатся 5 приложений — это служебные приложения Tomcat, необходимые для упрощения работы с ним. В будущем их можно будет удалить.

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Ниже находится раздел Deploy. С его помощью можно выбрать war-архив для развертывания. Пропишем путь и контекст вручную:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Нажимаем “Deploy”, видим, что в разделе Applications появилось наше приложение:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнерС помощью графического интерфейса Tomcat мы его можем останавливать, перезапускать, устанавливать длину сессии и удалять. При развертывании мы указали контекст /demo, а значит, обращаться к нашему приложению нужно по ссылке http://localhost:8080/demo. Проверь, все должно работать.

Через файловую систему

Чтобы задеплоить приложение таким способом, необходимо открыть директорию, в которой разархивирован Tomcat, перейти в webapps. Здесь находятся знакомые нам служебные приложения:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

Все, что требуется от нас — переместить сюда наш servlet.war.

Ждем несколько секунд, видим, что появилась новая папка servlet, а это значит, что наше приложение развернуто. Переходим в знакомый нам Application Manager интерфейс — http://localhost:8080/manager/. Здесь мы видим, что наше приложение развернуто в контексте /servlet:

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

При развертывании таким способом, контекст автоматически присваивается по названию развернутого war-архива. Для смены контекста можно переназвать новосозданную папку с приложением, но перед этим нужно удалить варник: в ином случае Tomcat повторно развернет приложение с именем архива.

Как видишь, деплоить приложения в Tomcat намного проще, чем может показаться. Но и другими его функциями пользоваться несложно. Давай проверим.

Использование HTTPS протокола вместо HTTP

Генерация сертификата

Настраиваем сервер

Динамическая генерация HTML-страниц

Альтернативы Tomcat

GlassFish — контейнер с открытым исходным кодом, разработку которого поддерживает Oracle.

В отличие от Tomcat, это полноценный веб-сервер, который кроме сервлетов может оперировать и другими компонентами из фреймворка JavaEE. В то же время, он использует намного больше оперативной памяти. Более гибкий при тонкой настройке сервера, что усложняет его использование. Стоит использовать при разработке приложений на фреймворке JavaEE.

WildFly, как и GlassFish, — полноценный веб-сервер. Кстати, под капотом WildFly использует Tomcat, как контейнер сервлетов. В отличии от GlassFish, WildFly более легковесный и простой в настройке.

Jetty — аналогично предыдущим имеет открытый исходный код. Развивается компанией Eclipse.

Как и Tomcat, является простым контейнером сервлетов, без поддержки всех компонентов фреймворка JavaEE. В то же время, он более легковесный, и его можно запустить даже на мобильном телефоне. Он быстро запускается и останавливается, хорошо масштабируется. В отличие от Tomcat, имеет меньшее комьюнити и базу знаний.

WebLogic — лицензированное программное обеспечение, требующие покупки перед использованием. Принадлежит компании Oracle.

По сравнению с Tomcat, его функционал немного шире. Может работать с протоколом ftp. Но он не настолько гибкий при разработке и тестировании приложений.

WebSphere ( WebSphere Application Server, если быть точным) — платное программное обеспечение. Разрабатывается компаниеей IBM. Аналогично WildFly и GlassFish является полноценным сервером приложений. Но у него более дружелюбный интерфейс настройки, плюс высокая надежность в работе.

Из минусов — он использует очень много ресурсов, долго запускается и останавливается, что не очень удобно при разработке небольших проектов.

Какой контейнер сервлетов или сервер приложений выбрать, зависит от конкретного проекта. Бывают проекты, где даже явный аутсайдер сможет проявить себя максимально качественно, но на первых порах лучше качественно разобраться с чем-то одним. Наверное, идеальный кандидат на роль этого одного — Tomcat. Первые шаги в его изучении мы уже сделали, а дальше дело за тобой! В завершающих статьях цикла “Введение в Enterprise-разработку” мы с тобой познакомимся с паттерном MVC. Часть 7. Знакомство с паттерном MVC (Model-View-Controller)Часть 8. Пишем небольшое приложение на spring-boot

Источник

Собеседование по Java EE — JEE Servlet API (вопросы и ответы)

Вопросы и ответы по сервлетам (servlets) в разделе Java Enterprise Edition — JEE Servlets API.

к списку вопросов раздела JEE

Вопросы

1. Что такое сервлет?
2. Какова структура веб-проекта?
3. Что такое контейнер сервлетов?
4. Какие задачи, функциональность контейнера сервлетов?
5. Что вы знаете о сервлет фильтрах?
6. Зачем нужны слушатели в сервлетах?
7. Когда вы будете использовать фильтры, а когда слушатели?
8. Как обработать исключения, выброшенные другим сервлетом в приложении?
9. Что такое дескриптор развертывания?
10. Как реализовать запуск сервлета с запуском приложения?
11. Что представляет собой объект ServletConfig?
12. Что представляет собой объект ServletContext?
13. В чем отличия ServletContext и ServletConfig?
14. Что такое Request Dispatcher?
15. Как можно создать блокировку (deadlock) в сервлете?
16. Как получить адрес сервлета на сервере?
17. Как получить информацию о сервере из сервлета?
18. Как получить ip адрес клиента на сервере?
19. Что вы знаете о классах обертках (wrapper) для сервлетов?
20. Каков жизненный цикл сервлета и когда какие методы вызываются?
21. Какие методы необходимо определить при создании сервлетов?
22. В каком случае вы будете переопределять метод service()?
23. Есть ли смысл определить конструктор для сервлета, как лучше инициализировать данные?
24. В чем отличия GenericServlet и HttpServlet?
25. Как вызвать из сервлета другой сервлет этого же и другого приложения?
26. Что вы знаете и в чем отличия методов forward() и sendRedirect()?
27. Стоит ли волноваться о “многопоточной безопасности” работая с сервлетами?
28. В чем отличие между веб сервером и сервером приложений?
29. Какой метод HTTP не является неизменяемым?
30. Почему HttpServlet класс объявлен как абстрактный?

31. В чем разница между методами GET и POST?
32. Что такое MIME-тип?
33. Назовите преимущества Servlet над CGI?
34. Какие наиболее распространенные задачи выполняемые в Servlet контейнере?
35. В чем разница между PrintWriter и ServletOutputStream?
36. Можем ли мы получить PrintWriter и ServletOutputStream одновременно в сервлете?
37. Расскажите о интерфейсе SingleThreadModel.
38. Какие существуют атрибуты у сервлетов и какая сфера их применения?
39. Почему необходимо переопределить только init() метод без аргументов?
40. Что означает URL encoding? Зачем нужны методы java.net.URLEncoder.encode() и decode()?
41. Зачем нужны и чем отличаются методы encodeUrl() и encodeRedirectUrl()?
42. Какие различные методы управления сессией в сервлетах вы знаете?
43. Что означает URL Rewriting?
44. Как применяются Cookies в сервлетах?
45. Как уведомить объект в сессии, что сессия недействительна или закончилась?
46. Какой существует эффективный способ удостоверится, что все сервлеты доступны только для пользователя с валидной сессией?
47. Как мы можем обеспечить transport layer security для нашего веб приложения?
48. Как организовать подключение к базе данных и обеспечить логирование log4j в сервлете?
49. Какие важные особенности существуют в Servlet 3?
50. Какие различные способы аутентификации сервлета?
51. Написать сервлет, реализующий загрузку файла на сервер.

Ответы

1. Что такое сервлет?

Сервлет является интерфейсом Java, реализация которого расширяет функциональные возможности сервера. Сервлет взаимодействует с клиентами посредством принципа запрос-ответ.
Хотя сервлеты могут обслуживать любые запросы, они обычно используются для расширения веб-серверов. Для таких приложений технология Java Servlet определяет HTTP-специфичные сервлет классы. Пакеты javax.servlet и javax.servlet.http обеспечивают интерфейсы и классы для создания сервлетов.

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер

2. Какова структура веб-проекта?

src/main/javaApplication/Library sources
src/main/resourcesApplication/Library resources
src/main/filtersResource filter files
src/main/webappWeb application sources
src/test/javaTest sources
src/test/resourcesTest resources
src/test/filtersTest resource filter files
src/itIntegration Tests (primarily for plugins)
src/assemblyAssembly descriptors
src/siteSite
LICENSE.txtProject’s license
NOTICE.txtNotices and attributions required by libraries that the project depends on
README.txtProject’s readme
http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

3. Что такое контейнер сервлетов?

Контейнер сервлетов — программа, представляющая собой сервер, который занимается системной поддержкой сервлетов и обеспечивает их жизненный цикл в соответствии с правилами, определёнными в спецификациях.

Известные реализации:Apache Tomcat, Jetty, JBoss, GlassFish, IBM WebSphere, Oracle Weblogic.

4. Какие задачи, функциональность контейнера сервлетов?

Контейнер сервлетов может работать как полноценный самостоятельный веб-сервер, быть поставщиком страниц для другого веб-сервера, например Apache, или интегрироваться в Java EE сервер приложений. Обеспечивает обмен данными между сервлетом и клиентами, берёт на себя выполнение таких функций, как создание программной среды для функционирующего сервлета, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.

5. Что вы знаете о сервлет фильтрах?

Сервлетный фильтр, в соответствии со спецификацией, это Java-код, пригодный для повторного использования и позволяющий преобразовать содержание HTTP-запросов, HTTP-ответов и информацию, содержащуюся в заголовках HTTP. Сервлетный фильтр занимается предварительной обработкой запроса, прежде чем тот попадает в сервлет, и/или последующей обработкой ответа, исходящего из сервлета.Сервлетные фильтры могут:

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

Метод init() вызывается прежде, чем фильтр начинает работать,и настраивает конфигурационный объект фильтра. Метод doFilter выполняет непосредственно работу фильтра. Таким образом, сервер вызывает init() один раз, чтобы запустить фильтр в работу, а затем вызывает doFilter() столько раз, сколько запросов будет сделано непосредственно к данному фильтру. После того, как фильтр заканчивает свою работу, вызывается метод destroy() .

Java Servlet Filter Example Tutorial: http://www.journaldev.com/1933/java-servlet-filter-example-tutorial

6. Зачем нужны слушатели в сервлетах?

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

7. Когда вы будете использовать фильтры, а когда слушатели?

Servlet Listener Example: http://www.journaldev.com/1945/servlet-listener-example-servletcontextlistener-httpsessionlistener-and-servletrequestlistener

8. Как обработать исключения, выброшенные другим сервлетом в приложении?

Т.к. браузер понимает только HTTP, то когда приложение выбросит исключение контейнер сервлетов обработает исключение и создаст HTTP response. Это аналогично тому что происходит при кодах ошибок вроде 404, 403 и т.д. Servlet API предоставляет поддержку собственных сервлетов для обработки исключений и ошибок, которые мы можем задать в дескрипторе развертывания. Главная задача таких сервлетов — обработать ошибку или исключение и отправить понятный HTTP ответ пользователю. Например, можно предоставить ссылку на главную страницу, а так же описание некоторых деталей об ошибке.

Источник

Контейнер серверного java-кода с поддержкой постоянного соединения

Disclaimer

Все, описанное в статье, является личным практическим опытом и не претендует на звание «истины в последней инстанции».

Преамбула

Здравствуйте. Я увлекаюсь созданием компьютерных игр. Моим любимым направлением, в котором я постоянно стараюсь совершенствоваться и узнавать что-то новое, являются браузерные многопользовательские игры.
Для создания прототипа для одной идеи в качестве контейнера сервлетов используется Apache Tomcat. Он общается с клиентской частью по http протоколу. Для такого типа игры схема вполне действующая, причем достаточно простая в реализации.
Но одной из преждевременных оптимизаций(да, это плохо, но тут я решил себе это позволить) стала идея использовать постоянное соединение между сервером и клиентом, т.к. в такой схеме не тратится время на открытие\закрытие соединения в каждом запросе. Для реализации схемы рассматривалось WebSocket API для Tomcat, но стало интересно написать свой велосипед, поэтому, встречайте рассказ о разработке под катом.

Инструменты

Архитектура

что такое сервлет контейнер. Смотреть фото что такое сервлет контейнер. Смотреть картинку что такое сервлет контейнер. Картинка про что такое сервлет контейнер. Фото что такое сервлет контейнер
Сначала рассмотрим логику работы приложения:

Контейнер представляется главным классом SocketServletContainer. Он служит для запуска/остановки контейнера, также содержит методы для управления сервлетами. Хочу заметить, что в статье термин сервлет обозначает объект, содержащий в себе метод с серверным кодом, и не имеет ничего общего со спецификацией Servlet от JCP. Просто мне удобнее называть такие объекты именно сервлетами.

Собственно, мы имеет базовый класс Servlet, от которого наследуются все сервлеты пользователя, класс сессии соединения(SocketSession), служащий для хранения информации о сессии и для отправки сообщений пользователю(почему я сделал именно так, объясню позже). Также были реализованы классы входящего и исходящего буфера(InputBuffer и OutputBuffer) соответственно.

Также понадобилось реализовать вспомогательный класс Config, отвечающий за парсинг файла конфигурации в формате xml. Следует упомянуть и о классах QueueHandler и TaskHandler.

QueueHandler является обработчиком очереди запросов и содержит метод для добавления экземпляра класса Task на обработку.
TaskHandler реализует интерфейс Runnable. В методе run содержится обработка переданного запроса.
Класс Task содержит в себе информацию о пришедшем запросе(к какому сервлету обратиться и параметры, переданные на сервер) и методы для работы с сетью(read\write).

Теперь рассмотрим организацию работы с сетью:

Я не буду подробно расписывать работу с Netty, потому что это уже сделали до меня( отдельное спасибо хабраюзеру Rena4ka за ее статью по Netty). Читайте на хабре или документацию на официальном сайте, как вам будет удобнее. Рассмотрю только ту часть, которая необходима для понимания основных принципов человеком, не имеющим опыта программирования с Netty.
Класс ServerPipelineFactory является фабрикой ChannelPipeline и нужен для функционирования Netty. Также пришлось реализовать 3 класса: Decoder, Encoder, NioHandler.
Первые 2- это обработчики пакетов, пришедших на сервер. Декодер отвечает за правильный разбор пакета, поступившего из сети и возвращает экземпляр класса Task. Encoder отвечает за корректную запись экземпляра Task в сеть и отправку на клиент.
NioHandler, по сути, является сетевым менеджером: принимает соединения, отправляет задачи на обработку и управляет сессиями.

Протокол

Для общения клиента и сервера нужен свой протокол. Я решил сделать его достаточно простым и текстовым.
В итоге, клиент посылает на сервер строку запроса, имеющую следующий вид: имя_сервлета[sysDiv]параметры_запроса.
Формат списка параметров запроса: name1=value1, name2=value2,…

Пример: «TS[sysDiv]message=Hello habrahabr.ru».

Нужно заметить, что протокол является симметричным в том смысле, что клиент получает строку с указанием сервлета, сформировавшего ответ, и списком переданных параметров.

А теперь перейдем непосредственно к рассмотрению кода нашего контейнера. Но обо всем по порядку.

Формат конфигурационного файла

workThreadCount — число потоков, который принимают сообщения из сети и пишут в сеть(нужно для инициализации Netty).
processThreadCount — число потоков, обрабатывающих общую очередь запросов, пришедших на сервер. В них, собственно, происходит парсинг строк-запросов, работа всего серверного кода и формирование ответов.

SocketServletContainer

Данный класс представляет собой синглтон, поскольку он является «центральным» классом и так к нему будет удобнее обращаться с других классов программы. И, разумеется, подразумевается 1 копия сервера на приложение(поэтому не требуется потокобезопасная реализация синглтона). Что, по моему мнению, логично.

Servlet

Тут все просто и понятно. Метод doRequest вызывается, когда приходит пакет с указанием вызвать данный сервлет.
Зам: передача сессии в метод doRequest сделано с той целью, чтобы сервлет мог получить List всех имеющихся сессии и разослать им сообщение. Например, при реализации чата.

SocketSession

Каждая сессия имеет свой уникальный id. Существует пул id-ников на 20000 подключенных клиентов. При превышении этого лимита сервер, при попытке создать сессию, будет логировать ошибку, отправлять сообщение об ошибке не клиент и закрывать канал.
Значение размера пула лучше вычислить опытным путем, в идеале он должен быть чуть больше числа максимально возможных одновременно подключенных клиентов на вашем сервере.

InputBuffer

В конструкторе происходит инициализация, строка source должна содержать список параметров запроса в заданном формате.

OutputBuffer

Интерфейс класса достаточно понятен. Важное замечание- нужно переопределить метод toString(), поскольку именно он используется для формирования ответа в классе SocketSession.

Config

Реализацию этого класса я приводить не буду, потому что интерфейс его понятен из того, что используется в SocketServletContainer, а реализаций xml-парсеров на java в интернете достаточно много и, я надеюсь, читатель найдет для него наиболее подходящую.
Лично я использовал DOM-парсер.

QueueHandler

Данный класс тоже очень прост в реализации. Внутри он содержит пул потоков, который занимается выполнением задач(TaskHandler). Планирование я переложил на надежную и проверенную реализацию threadPool. Для создания пула используется фабрика Executors.newFixedThreadPool(n).

При вызове метода stop, уже имеющиеся задачи, стоящие в очереди, будут обработаны, но новые TaskHandler-ы на обработку приниматься уже не будут.

TaskHandler

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

Объект Task имеет поля «имя сервлета» и «буфер». Буфер является строкой параметров запроса.
Статичные методы write/read требуется для получения экземпляров класса/ записи в канал для работы Netty.

Сетевая часть

Как и обещал, подробно рассматривать работу с netty я не буду, просто приведу код и поясню моменты, которые касаются реализации логики.

ServerPipelineFactory

Decoder

Пакет на сервер приходит в следующем формате: первые 4 байта- длина «полезных» данных, далее идут сами данные. Decoder реализует считывание, чтобы в слоях, расположенных выше, мы могли не думать о том, что данные еще не пришли полностью.

Encoder

NioHandler

Этот объект обрабатывает основные события работы с сетью: подключение клиентов, получение сообщений, обрыв соединения.

Пример сервлета

Как это работает или главный класс приложения

Собственно, в приложении не так уж много строк кода, все просто и прозрачно.

Немного тестов

Что ж, контейнер написан, он работает. Заморачиваться с созданием клиентской обертки под него я не стал, ограничился прямой записью в сокет, выглядит это примерно так:

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

Собственно, я решил сравнить это решение с контейнером сервлетов, работающем по http.
Для тестов был написан сервлет, крутящийся в Tomcat и сервлет, работающий внутри созданного контейнера.

Зам: Я намеренно сравнил производительность http-протокола и решения на сокетах, поскольку web-socket, которые Tomcat успешно поддерживают, мной не рассматривались для реализации данного проекта игры.

Мы имеем 2 результата, различающихся на порядок. Но с учетом того, что мысль использовать сокеты пришла ко мне не из-за скорости, а из-за необходимости иметь возможность достучаться от сервера к клиенту, результат можно признать более, чем удовлетворительным.

Также остался небольшой список, что еще можно было бы реализовать для подобной системы, который я также приведу:

Вместо заключения

Результаты работы контейнера вполне удовлетворили мои ожидания. Использование NIO позволило экономично расходовать потоки и сконфигурировать контейнер под имеющееся железо так, чтобы он работал максимально эффективно.
Функционал, который предоставляет контейнер, позволяет достаточно удобно разрабатывать приложение, не заботясь о «низкоуровневых» вещах, типа парсинга пакетов и так далее(мне, привыкшему разрабатывать на tomcat, все показалось достаточно удобным:)).

Но я все-таки не решился использовать подобное решение как основу реального проекта, потому что для меня наличие сокетов, конечно, было бы очень кстати(для обратной связи сервер-клиент), но, в принципе, не критично. А вот производительность и надежность Tomcat, проверенного годами и тысячами разработчиков, не вызывает вопросов.
Я планирую использовать реализованную систему в «узких», но некритичных местах, в которых http-протокол использовать совсем уж нехорошо, например, она отлично подойдет для реализации чата.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *