Чат на Erlang и Web Sockets

Apr 16, 2010 19:22

Данный чат в первую очередь задумывался как демонстрационный пример для моего доклада про веб сокеты на РИТ-2010. То есть в первую очередь он создавался чтобы протестировать веб сокеты, проверить как будет работать event-driven система, состоящая из брауера, сервера и среды передачи данных. То, что это все хорошо работает по отдельности - уже давно известно и не интересно.
Выбор Эрланга для написания сервера обусловлен двумя вещами:
- во-первых, он мне очень интересен и хотелось написать несложную программу в самообразовательных целях :)
- во-вторых, сама модель работы процессов и асинхронных коммуникаций в Эрланге как нельзя лучше подходит для реализации событийно-ориентированных вещей.
Поскольку пример демонстрационный, то дизайн сделан довольно спартанский - ровно такой, чтобы не мешал. Аналогично не делалось никакой оптимизации, защиты от хаксоров и всего прочего, что необходимо в бою.

Посмотреть можно вот тут: http://chat.websockets.ru

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

Приняв подключение, сервер добавляет процесс, отвечающий за коммуникацию с клиентом, в свой список клиентов, а потом присылает его пользователю. Для этого он посылает (в эрланговском смысле: Pid ! Msg) сообщение процессу клиента с подготовленным списком.

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

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

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

Если пользователь не авторизован, то система не принимает от него сообщения. Состояние авторизации хранится в record`е - пока это еще рано называть FSM`ом. Изначально мы находимся в состоянии, в котором отказываем пользователю в отправке сообщения - возвращаем ошибку. Это можно легко проверить если с помощью FireBug или DevTools сделать видимым слой #messagediv и отправить сообщение.

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

Код выложен на гитхабу: http://github.com/lisitsky/wisechat/blob/master/src/wisechat.erl
Я буду очень благодарен нашим гуру, если они устроят жесткую немецкую небольшую "порку".

event-driven, чат, эрланг, erlang, chat, web sockets

Previous post Next post
Up