2016-03-18 2 views
3

Я работаю над серверным/клиентским приложением, которое позволяет подключать несколько клиентов к серверу в любой момент времени. Для каждого клиента сервер устанавливает объект ClientHandler, который имеет входной и выходной поток для клиента, подключенного к этому сокету. Благодаря этому соединению клиент может отправлять несколько сообщений на сервер в любой момент на протяжении всей программы, и сервер будет отвечать в соответствии с сообщением.Java - распознавание отправленных сообщений и отправленных сообщений с сервера на стороне клиента

Что мне нужно реализовать - это механизм, который отправляет в определенные моменты сообщения всем клиентам, подключенным в настоящее время. Я сделал это, сохранив все выходные потоки для клиентов в ArrayList<PrintWriter>, которые позволят отправлять одно и то же сообщение всем клиентам.

То, что я борюсь с таким:

Когда сообщение получено, что является индивидуальным для клиента, GUI клиента обновляются соответствующим образом (только определенное число сообщений может быть отправлено, так что только избранной количество возможных ответов от сервера, которые рассматриваются с помощью клиентских инструкций if). Однако, когда сообщение получено клиентом, который был отправлен всем клиентам, я хотел бы, чтобы клиент обновил GUI совершенно по-другому.

Учитывая, что обе формы ввода поступают из одного входного потока, я вижу, что это трудно, и я ожидаю, что мне придется объявлять любые методы, которые вызывают вывод с использованием , должны быть сделаны . Однако есть ли способ обработки разных входов при использовании того же PrintWriter? Должно ли это быть сделано с использованием дополнительных операторов if или это можно сделать с помощью отдельного Thread на стороне клиента, который обрабатывает сообщения, отправленные всем клиентам?

Спасибо за любой совет, если вы считаете, что можете помочь, не стесняйтесь просить части моего существующего кода!

Марк

+0

Я немного смущен здесь. Вы говорите о стороне сервера (отправляя сообщения всем клиентам), тогда вы говорите о стороне клиента (обновляя графический интерфейс), а затем вдруг добавляете потоки, принадлежащие серверу или клиенту? Похоже, у вас есть отдельные проблемы, но вы их смешиваете. Для части сообщения вам, очевидно, нужно как-то пометить широковещательные сообщения в своем протоколе, и это не имеет ничего общего с синхронизацией потоков. –

+0

Благодарим вас за это, когда вы говорите «как-то пометить широковещательные сообщения», вы имеете в виду что-то вроде отправки логических данных до содержимого сообщения, которое может быть обнаружено на стороне клиента? @SergeyTachenov – marcuthh

+0

Я не могу сказать, не зная подробностей вашего протокола. Это что-то, что вы можете переделать? Какой формат он использует? Может ли он быть расширен или переработан? Например, если он использует XML-сообщения, то просто добавление атрибута «broadcast = 'true» будет выполняться. «Отправка булевых до содержимого» также звучит похоже, хотя и слишком наивна для четко определенного протокола. –

ответ

1
 When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client. 

теперь, если вы просто держать добавление клиентского сокета к ArrayList в ваше время цикл, вы будете иметь список клиентов, активно связанных с вашим сервером, как:

после акцепта:

clients = new ArrayList<DataOutputStream>(); 
    Socket socket = ss.accept(); 
    os = new DataOutputStream(socket.getOutputStream()); 
    clients.add(os); 

Теперь, когда у вас есть все клиенты в том, что клиенты ArrayList, вы можете цикл через него, или с некоторым протоколом определите, с каким клиентом я должен отправить d ata после чтения.

3

Вы в первую очередь не хватает протокола между сервером и вашим клиентам!

Очевидно, что сервер может отправлять два типа сообщений «ответ» и «трансляция». Довольно простой подход - это пометка ваших сообщений: например. префикс ваших сообщений с помощью «R», если это ответ на запрос и с «B», если это сообщение автоматической трансляции. (Это все зависит от того, как должна выполняться связь между сервером и клиентами.)

Независимо от того, нужен ли вашему клиенту разные темы для обработки сообщений, это совершенно другая история. Наличие разных потоков полезно, если активность обработки внутри вашего клиента будет препятствовать своевременному считыванию сокета. Тогда вы можете подумать о том, что поток ввода-вывода, который выполняет связь, и отправляет сообщения различным «обработчикам» (может быть другим потокам) для обработки. (Этот поток ввода-вывода также может удалить тег таким образом, что существующий код обработки не должен знать о нижнем протоколе с сервером.)

Аналогичная аргументация может быть применима к вашей стороне сервера. В зависимости от динамики взаимодействия и обработки запросов вы можете использовать несколько потоков.Тогда вы должны иметь один, который делает ввод/вывод с клиентами и другими, которые делают работу (генерирующие ответы или широковещательные сообщения)

+0

Привет, вы подняли очень интересный момент, который, я чувствую, это то, что я, возможно, искал. Вы указываете «отправка сообщений различным обработчикам», что может работать в моей ситуации. Я искал способ передать сообщения в другой поток, но не смог найти что-либо подходящее. В моей текущей версии я решил, что для двух потоков используется один и тот же объект «Scanner», но совсем не нравится. Не могли бы вы добавить пример передачи обработанного сообщения в другой поток? Спасибо – marcuthh

+0

Самый простой был бы синхронизированный список или очередь, разделяемая потоками, где один поток вставляет _message_ экземпляры, а другой читает сообщения. Вы можете прочитать о ** BlockingQueue ** для легкости синхронизации в пустой очереди. – rpy

+0

Мне сказали не использовать BlockingQueue, так как я должен следовать приведенной спецификации. Есть ли альтернативный способ? – marcuthh