При реализации серверного приложения нужно преодолеть некоторые сложности, связанные с тем, что к серверу будут постоянно подключены сразу несколько пользователей, причем информация о каждом пользователе будет постоянно храниться и использоваться сервером. Нужно также обеспечить надежную работу клиентского, а главное – серверного приложения при проблемах, связанных с неисправностями сети.
И, наконец, нужно обеспечить автоматическую рассылку клиентским приложениям следующей информации (клиенты эту информацию специально с сервера не запрашивают):
• текста сообщений;
• уведомлений о присоединении или отсоединении пользователей.
Формат сообщений клиента и сервера
Клиент и сервер обмениваются только текстовыми сообщениями (не путать с сообщениями, которыми обмениваются пользователи в ходе разговора). Строка любого сообщения состоит из двух частей: префикса и текста сообщения. Префикс отделяется от текста сообщения символом: (двоеточие). По префиксу можно определить, что делать с полученным сообщением.
Возможны следующие сообщения от клиента серверу:
• name: имя_пользователя – при помощи этого сообщения клиентская программа сообщает серверу, под каким именем зарегистрировать пользователя (это имя будут видеть другие пользователи);
• text: текст – при получении этого сообщения сервер должен разослать текст всем участникам разговора (включая отправителя);
• имя_адресата: текст – при получении этого сообщения сервер должен отправить текст только заданному префиксом пользователю имяадресата, а также должен отправить копию автору сообщения.
К сообщениям третьего типа относятся все сообщения, принимаемые сервером и не начинающиеся с text: или name:.
В свою очередь, сервер может посылать клиентской программе сообщения следующего вида:
• ok: – означает, что пользователь зарегистрирован и может вступать в разговор;
• error: сообщение_об_ошибке – означает, что по каким-то причинам пользователь не может участвовать в разговоре. При получении этого сообщения клиентская программа должна показать окно с текстом сообщение_об_ошибке и разорвать соединение с сервером;
• adduser: имя_пользователя – при получении такого сообщения клиентская программа должна добавить строку имя_пользователя в список участников разговора;
• deluser: имя_пользователя – при получении такого сообщения клиентская программа должна удалить строку имя_пользователя из списка участников разговора;
• text: текст – клиентская программа должна добавить текст к тексту разговора.
Перед рассмотрением реализации клиентской и серверной частей скажем несколько слов об использовании специальных сообщений клиента (name: имя пользователя) и сервера (ok: и error: сообщение_об_ошибке). Дело в том, что в предлагаемой реализации сервера присоединение нового пользователя к разговору происходит следующим образом.
1. Клиентское приложение присоединяется к серверу (количество пользователей ограничено, поэтому сервер может послать лишнему пользователю сообщение error: с соответствующим текстом, описывающим ошибку, и тут же разорвать установленное соединение).
2. Клиентское приложение посылает серверу сообщение с именем пользователя (префикс name:).
3. Если имя, под которым хочет зарегистрироваться новый пользователь, используется, то клиентскому приложению отправляется сообщение error: с пояснением ошибки.
4. Если имя свободно, то сервер сохраняет его (и рассылает его всем остальным клиентским приложениям), а также посылает приложению присоединенного пользователя список всех остальных пользователей, и только после этого дает новому пользователю возможность участвовать в разговоре (сообщение ok:).
Остальные нюансы будут рассмотрены при описании исходного кода клиентского и серверного приложений.
Реализация сервера
Серверное приложение реализовано с оконным интерфейсом. Форма f rmServer приложения во время работы представлена на рис. 11.6.
Рис. 11.6. Форма сервера сообщений