viogull
@viogull
Исследователь

Как отправить сообщение всем клиентам, подсоединенным к серверу?

Пробую написать чат з архитектурой клиент-сервер. Сервер базируется на Java Socket'ах . Клиент на Android.
Я создал класс Message, реализующий интерфейс Serializable. Собственно, клиент и сервер обмениваются объектами этого класса.
Авторизацию и регистрацию мне удалось сделать. Проблема возникла в следующем: клиент отправляет сообщение, которое должно попасть в групповой чат. То есть, сервер должен после принятия этого сообщения отправить его всем онлайн-клиентам, чтобы они его отобразили у себя. И это самое сообщение я не могу отослать.
Делал следующее:
/*
 socketList - static LinkedList<Socket>
 globalMessage- объект сериализуемого класса Message
 client - Socket объект клиента от которого приходит сообщение
*/


for (Socket socket : RServer.socketList) {
    if (!socket.equals(client) & !socket.isClosed()) {
        try {
            ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
            os.flush();
            os.writeObject(globalMessage);
            os.close();
        } catch (SocketException ex) {
            ex.printStackTrace();
        }
    }


}


На клиенте в фоне крутится такая функция.
public void listenServerMessages() {
    try {
        while (true) {
            Message message = (Message) objectInputStream.readObject();
            if (message.getType() == Message.MESSAGE & !message.isErr()) {
                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setDate(DateFormat.getDateTimeInstance().format(new Date()));
                chatMessage.setMe(false);
                chatMessage.setMessage(message.getMessage());
                displayMessage(chatMessage);
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    /*
    ChatMessage - класс сообщения в главной View чата
    
    */
}


Возможно, этот подход неправильный ибо сам сервер без запроса не должен что-то отправлять. По-этому задам заодно следующий вопрос - может лучше сделать таблицу в БД, и сохранять туда всю переписку, а на клиенте делать в фоне запрос к серверу, чтобы последний возвращал новые сообщения? Если так, то с каким периодом нужно делать такие запросы?
  • Вопрос задан
  • 1781 просмотр
Решения вопроса 1
jaxtr
@jaxtr
JavaEE/Spring-разработчик
В целом подход нормальный, но нужно вручную управлять соединениями. Для упрощения этой задачи можно использовать Netty. На стороне клиента желательно в блоке while(true) добавить Thread.sleep(1), это добавит приостановку потока на 1 мс, но серьёзно снизит нагрузку на ЦП.

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

Войдите, чтобы написать ответ

Похожие вопросы