Simple Erlang TCP server application
Why use Java for server-side applications if there is Erlang?
Java. Эта платформа до сих пор пользуется популярностью лишь из-за того, что огромное количество серверных приложений создаются на JavaEE ++ Hibernate ++ Spring ++ whatever. Все не раз читали рекламные брошюры про быстроту и удобство создания таких приложений и про их надежность.
Большинство компаний, занимающихся «enterprise» разработками будут использовать подобные инструменты, просто потому, что this is the way it is. Почему огромное количество людей программирует на Java? Как правило, еще в учебном заведении люди знакомятся с C/C++. Знакомство это является скоротечным и очень болезненным, большинство людей так и не понимают, как уследить за памятью и за границами объектов в сотне строк кода. Я уже не говорю про такие вещи, как умышленный выход за границы объектов, это в наше время вообще высший пилотаж программирования на C. Разумеется, познакомившись с Java, эти люди воспринимают ее как манну небесную, избавление от постоянных сегфолтов, утечек памяти и «очень странного» поведения написанного ими кода. Большое число этих людей даже не отдает себе отчета в том, какой кактус они едят, а среди тех, кто это понимает что-либо сказать против использования Java могут лишь единицы.
Данная ситуация достаточно точно описана здесь
А что же можно предложить вместо Java для создания серверных приложений? Каким вообще должно быть серверное приложение?
Да много каким, но, во-первых, серверное приложение должно быть многопоточным. Это приводит нас к выводу, что язык и набор библиотек, которые мы хотим использовать должны предоставлять средства для простого и надежного создания многопоточных приложений. Никакой императивный язык не позволит организовать несколько потоков, да еще и взаимодействующих друг с другом, без головной боли. Какими бы ни были средства, которые будут для этого использованы, вы упретесь в проблему изменяемого состояния. А здесь семафоры, блокировки, синхронизация, все радости жизни.
В Эрланге новый тред порождается функцией spawn(). That’s it. Если вы хотите послать сообщение процессу, вы используете конструкцию вида Pid ! Message, где «!» — оператор посылки сообщения процессу. Если в вашем процессе вы хотите обрабатывать получаемые сообщения вам достаточно использовать конструкцию вида
И все! процесс будет обрабатывать входящие сообщения по мере их поступления. Erlang подталкивает программиста к идее «чем больше тредов — тем лучше».
В типичных серверных приложениях, как правило возникает несколько типовых задач: получение сообщений от клиентов, обработка этих сообщений, взаимодействие с базой данных, отправка сообщений клиентам.
В данной серии примеров описывается процесс создания TCP сервера, получающего информацию от клиентов в виде XML-докуметов. Сервер должен обработать входящие документы, где нужно — обратиться к БД и ответить клиенту.
Ok, let me put the code where my mouth is.
В первую очередь — информация о модуле, экспортируемых им функциях и макросы.
-define(TCP_OPTIONS,[binary,{packet,0},{active,false},{reuseaddr,true}]).
Теперь опишем функцию, стартующую наш сервер, слушающий определенный порт. Здесь мы используем модуль gen_tcp. Слушаем сокет, делаем accept.
Accept соединение и сразу же создаем новый тред, работающий с данным соединенением. Рекурсивно вызываем себя же, чтобы слушать другие соединения на сокете.
Треды в языке Erlang — функции, выполняемые в отдельном потоке. В нашем случае - это функция loop. Loop читает из сокета поток байт, конвертирует его в строку (в Erlang строка — это просто список чисел) и вызывает функцию обработки этой строки, определенную в модуле process_msg. Этот модуль в нашем сервере будет разбирать XML сообщения. Он будет описан в одном из следующих постов.
Как мы видим, данный код занял менее тридцати строк, при этом являясь многопоточным сетевым приложением. А теперь напишите аналогичное приложение на Java. А теперь напишите аналогичное приложение на С.

