- Java - из-за учебы было пару дней на написание программ, поэтому пошел по легкому пути и решил писать на java. Так же благодаря этому программы получились кросс-платформенными. (при наличии большего времени использовал бы C++, тесты, к сожалению, не успел написать по той же причине)
- Так как сокеты используют TCP, то не пришлось заботиться о подтверждении получения сообщений и программы полагаются на то, что если метод отправки сообщений не выкинул исключение, то сообщение считается доставленным.
- Соединения не защищены, так как для этого нужен доверенный сертификат (который помешал бы запуску в локальной сети), а с добавлением само-подписного сертификата в клиент не успел разобраться. А так как соединения не защищены, то не видел смысла шифровать пароли на сервере.
- Так как пользователей может быть много, то для каждого нового сокета заводится отдельный поток-демон и ждать приходится только при обращении к общим полям сервера.
- По-хорошему для мессенджера надо использовать noSQL базу данных, но если я правильно понял, то задание рассчитано не на это и я использовал HashMap для хранения данных о пользователях.
- API рассчитан на асинхронное получение и отправку сообщений, чтобы не возникало проблем с получением любых данных в любой момент и можно было остановить потоки-демоны слушающие сокеты при остановке основного потока сервера без дополнительной обработки получения ошибок при ожидании ответа. (синхронные ответы ожидаются только при аутентификации)
- Для графического интерфейса клиента используется Swing, так как он уже есть в составе jdk и довольно прост в использовании.
- Для запуска достаточно запустить скрипт
jar.sh
, который создастclient.jar
иserver.jar
, которые можно запустить командойjava -jar *
. - jar-файлы уже созданы на случай наличия только JRE.
client
ожидает запуск в форматеclient [defaultHost [defaultPort]]
.server
ожидает запуск в форматеserver [port]
, по-умолчанию порт будет 31337.
Для корректной остановки сервера нужно ввестиstop
.
- Кодировка - UTF8
- В конце каждого сообщения должен идти символ перевода строки
auth <login> <password>
- попытка авторизации
reg <login> <password>
- попытка регистрации
В ответ на данные запросы придетAccepted
в случае успеха или сообщение с описанием ошибки в противном случае. ПослеAccepted
ожидается сообщение в форматеFriendsList <n>( <username> <id> <unreadMessages>){n}
.GetFriendsRequestsList
- извещает сервер о том, что мы хотим получить список запросов в друзья.AcceptRequest <id>
- сообщает серверу, что мы принимаем запрос от данного пользователя.SendRequest <username>
- посылает запрос заданному пользователю, если такой существует.SendMessage <id> <message>
- посылает сообщение заданному пользователю, если он уже есть в списке друзей.GetMessageFrom <id>
- извещает сервер о том, что мы хотим получить самое первое новое сообщение от заданного пользователя.
Notification <message>
- информационное сообщение.NewFriend <username> <id>
- сообщает, что в списке друзей пользователя появился новый пользователь.NumberOfRequests <n>
- сообщает количество запросов в друзья.RequestsList <n>( <username> <id>){n}
- список всех запросов в друзья.UnreadMessages <id> <n>
- сообщает количество новых сообщений от пользователя.NewMessage <id> <message>
- отправляет первое новое сообщение от пользователя.
Использованные условные обозначения:
<username> - имя пользователя, не должно содержать пробельных символов.
<password> - пароль пользователя, не должен содержать символов перевода строки.
<id> - id пользователя.
<n> - число.
<id>, <n> - целые, не отрицательные, беззнаковые числа.
<message> - сообщение, не должно содержать символов перевода строки.
<unreadMessages> - количество новых сообщений от пользователя.
(...){n} - n повторений сообщения внутри круглых скобок.