Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как написать чат на JAVA!(проблемы) 
V
    Опции темы
JlOKu
Дата 9.5.2006, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 30.4.2006

Репутация: нет
Всего: нет



Есть куча вопросов: вот начал писать столкнулся с такой проблемой.

У меня структура чата такая 

есть сервер и клиенты . Все клиенты соеденены с сервером.
Код

public Server() {
        
        
        
        message = new Message();
        quantityOfClient  = 0;
        try {
            socket = new ServerSocket(connectPort, 100);
            System.out.println("Wait connect client");
            while (true) {
                Socket connect = socket.accept();
                System.out.println("Client is connect");
                ReadThread readThread  = new ReadThread(connect,message,quantityOfClient);
                WriteThread writeThread = new WriteThread(connect,message,quantityOfClient);
                quantityOfClient++;
                readThread.start();
                writeThread.start();
                
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  

Для каждого клиента создается отдельный поток для чтения и записи.
У меня ни как не получается прочитать сообщение от клиента. Я пытаюсь сделать это так.
Код

public void run() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    readSock.getInputStream()));
            String nickName = in.readLine();
            System.out.println("Connect new User " + nickName);
            System.out.println("Ip of new User " + readSock.getInetAddress());
            message.setNewClient(nickName);
            message.setMessageForMain(nickName);
            
            
            for (;;) {
                in = new BufferedReader(new InputStreamReader(readSock.getInputStream()));
                int codeOfMessage = in.read()    ;
                String str        = in.readLine();
                System.out.println("new Message " + str  + "number " + codeOfMessage);
                if(str == null){
                    sleep(TIMEOUT);
                    continue;
                }else if(str.equalsIgnoreCase("-1")){
                    //to est on umer
                }
                message.setMessage(str,nick,codeOfMessage);
            }
        } catch (IOException e){
            e.printStackTrace();
            System.exit(1);
        }catch(InterruptedException r){
            r.printStackTrace();
            System.exit(1);
        }
    }


message это обьект , который содержит в себе сообщение , код сообщения и и ник клиента  , который положил это сообщение.
Вот!
Мне не понятно одно , как организовать общение между клиентом и сервером , когда неизвестно в какой момент времени клиент пошлет сообщение , и неизвестно в какой момент ответит сервер. Можно вместо BufferedReader написать InputStream и методом read (read блокирует поток , то есть ждет пока клиент что нить напишет , а это и нужно )прочитать сообщение по байтого , но так не пойдет потому , что чат должен поддерживать unicode.
За любой совет буду рад , спасибо заранее. 
PM MAIL   Вверх
LSD
Дата 9.5.2006, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



1. Вот реализации Jabber Server и Jabber Client на Java, может проще взять их и адаптировать под свои нужды?
2. И у клиента и у сервера есть поток который ждет пока поступят данные, он может делать с блокировкой до тех пор пока не поступят данные, а может и не ждать, а проверять скажем другие соединения на предмет наличия данных. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
JlOKu
Дата 16.5.2006, 06:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 30.4.2006

Репутация: нет
Всего: нет



Спасибо ! Есть еще один вопрос , вот на днях написал чат на JAVA  используя IMAP .Столкнулся с такой проблемой как кодировка , выяснил что на самом серваке русский шрифт не понимается. Я отправляю сообщение с помощю DataOutputStream , а    принимаю соответственным Input,  приходит клякса , может кто сталкивался с такой проблемой ? 

Это сообщение отредактировал(а) JlOKu - 16.5.2006, 07:03
PM MAIL   Вверх
LSD
Дата 17.5.2006, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



DataOutputStream пишет строки в кодировке UTF-8, возможно сервер требует себе другую кодировку. А вообще маловато данных, для того чтобы что-то советовать. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
JlOKu
Дата 18.5.2006, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 30.4.2006

Репутация: нет
Всего: нет



Всем спасибо за помощ , сдал все лабы удачно  smile . Вопрос с кодировкой не был решен , но был дан совет типа , лови событие когда меняется с англисского на русский , и когда отправляеш на сервак сообщение приписывай перед каждой русской буквой спец символ ( ASCII конечно ), а при прочитывании при встрече с символом переводи следующий символ  его на русский . Воть но это не обязательно еще раз всем спасибо. 
PM MAIL   Вверх
Wowa
Дата 30.6.2006, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: нет
Всего: 290



Цитата(LSD @  9.5.2006,  15:06 Найти цитируемый пост)
2. И у клиента и у сервера есть поток который ждет пока поступят данные, он может делать с блокировкой до тех пор пока не поступят данные, а может и не ждать, а проверять скажем другие соединения на предмет наличия данных.  

in.read() вроде как ждет до опупения, т.е. пока данные не придут мы имеет блокировку, которую ничем нельзя убрать. Но это имхо, не проблема, т.к. на каждого подключенного клиента можно просто создать отдельный Thread, который только его слушать будет. Или можно как-то иначе? 
PM WWW   Вверх
Wowa
Дата 30.6.2006, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: нет
Всего: 290



У меня проблема в том, что когда стартует на каждого клиента по отдельному Thread на сервере для чтения, то чтение идет нормально.
Но как только я запускаю еще один Thread на сервере, который каждую секунду перебирает сокеты клиентов и шлет на них определенную информацию, то Thread в которых должно происходить считывание с клиентов - вообще ничего не читает с них. 
PM WWW   Вверх
powerOn
Дата 30.6.2006, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 2
Всего: 159



вот мое скромное мнение по поводу чатов:

Создавать отдельные потоки и слушать сокеты -  много лишней работы. Чтобы упростить данный процесс, можно использовать технологию Java RMI. Клиент и серевер в данном случае будут предоставлять удаленные объект друг другу. Сервер предоставит объект регистрации и входа в систему и объекты для отправки сообщений. Клиент - предоставит объект, методы которого сможет вызывать сервер, например для отправки сообщений клиенту.

Общая схема такая: 
Сервер создает один общий для всех клиентов объект, предоставляющий услугу регистрации (входа в систему) клиенту. Все клиенты вызывают методы данного удаленного объекта, чтобы попасть в чат. Например, данный объект будет иметь метод login(String name, char [] password, MyCallbackObject clientCallback), а возвращать (в случае успешного входа) будет объект с методами sendMessage(String message). Клиент будет вызывать данный метод когда захочет отправить сообщение.
 
Сервер создает пул объектов обратной связи с клиентами. В данный пул помещается информация о клиенте и MyCallbackObject clientCallback клиента. Как только серверу станет необходимо отправить некоторое сообщение клиенту, он выберет из пула объект clientCallback нужного ему клиента и вызовет его метод (например) sendMessage(String message). Так клиент получит свое сообщение.

Плюсами данного подхода является отсутствие постоянного цикла прослушивания сокетов. Если говорить точнее, то это цикл будет скрыт от нас высокоуровневыми механизмами RMI. 

Извиняюсь, если сумбурно изложено. Желательно, сначало ознакомится с RMI, тогда картина сильно проясниться. Впрочем это лишь мои вольные мысли. 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
LSD
Дата 2.7.2006, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



Цитата(Wowa @  30.6.2006,  13:47 Найти цитируемый пост)
in.read() вроде как ждет до опупения, т.е. пока данные не придут мы имеет блокировку, которую ничем нельзя убрать. Но это имхо, не проблема, т.к. на каждого подключенного клиента можно просто создать отдельный Thread, который только его слушать будет. Или можно как-то иначе?

Там есть несколько вариантов, метода read()
  • int read() - действительно блокируемый
  • int read(byte[], int, int) - неблокируемый

Цитата(Wowa @  30.6.2006,  14:32 Найти цитируемый пост)
У меня проблема в том, что когда стартует на каждого клиента по отдельному Thread на сервере для чтения, то чтение идет нормально.Но как только я запускаю еще один Thread на сервере, который каждую секунду перебирает сокеты клиентов и шлет на них определенную информацию, то Thread в которых должно происходить считывание с клиентов - вообще ничего не читает с них.

Без кода, сложно что-то сказать.

Цитата(MoonCat @  30.6.2006,  15:13 Найти цитируемый пост)
Создавать отдельные потоки и слушать сокеты -  много лишней работы. Чтобы упростить данный процесс, можно использовать технологию Java RMI.

Можно, но тут есть некоторые проблемы:
1. Оптимизировать сервер по производительности будет проблематично (а RMI все таки довольно прожорливая до ресурсов технология)
2. Клиенты могут быть только на Java

Цитата(MoonCat @  30.6.2006,  15:13 Найти цитируемый пост)
а возвращать (в случае успешного входа) будет объект с методами sendMessage(String message). Клиент будет вызывать данный метод когда захочет отправить сообщение.

Что-то я не понял, что он будет возвращать, что за объект?

P.S. По теме рекомендую почитать: Instant Messaging in Java: The Jabber Protocols. У меня вроде где-то валялась в электронном виде. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
powerOn
Дата 2.7.2006, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 2
Всего: 159



Цитата(LSD @  2.7.2006,  17:52 Найти цитируемый пост)
Можно, но тут есть некоторые проблемы:
1. Оптимизировать сервер по производительности будет проблематично (а RMI все таки довольно прожорливая до ресурсов технология)

Согласен конечно, будут вопросы с производительностью. Тогда можно RMI компоненты заменить на EJB. Принцип один и тот же, но последний работает на сервере, который решает вопросы масштабируемости и производительности.

Цитата(LSD @  2.7.2006,  17:52 Найти цитируемый пост)
2. Клиенты могут быть только на Java

Ну тогда CORBA ждет...

Цитата(LSD @  2.7.2006,  17:52 Найти цитируемый пост)
Что-то я не понял, что он будет возвращать, что за объект?

Клиент подсоединяется к серверу, предает ему имя пользователя и пароль, на что сервер выполняет проверку клиента и в случае успеха
создаёт у себя новый RMI объект, реализующий методы отправки сообщений, и возвращает ссылку на него клиенту. Клиент получает данную ссылку (объект реально находится на стороне сервера) и использует её (вызывает методы) для отправки сообщений. Получается что-то вроде RMI CallBack-а, но не он. Так для каждого клиента будет свой RMI объект работающий на сервере, методы которых будут использованны для отправки сообщений. 

 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
LSD
Дата 2.7.2006, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



Цитата(MoonCat @  2.7.2006,  20:23 Найти цитируемый пост)
создаёт у себя новый RMI объект, реализующий методы отправки сообщений, и возвращает ссылку на него клиенту. Клиент получает данную ссылку (объект реально находится на стороне сервера) и использует её (вызывает методы) для отправки сообщений

Тогда он должен зарегистрировать этот объект в RMI-registry под новым именем и отправить это имя клиенту, и тот тогда сможет сделать lookup. Но на самом деле это плохо, т.к. имена всех зарегистрированных в RMI-registry объектов можно узнать, и можно тогда писать от имени любого клиента. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
powerOn
Дата 2.7.2006, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 2
Всего: 159



Цитата(LSD @  2.7.2006,  20:36 Найти цитируемый пост)
Тогда он должен зарегистрировать этот объект в RMI-registry под новым именем и отправить это имя клиенту, и тот тогда сможет сделать lookup.

Нет, этого не нужно делать. Достаточно вернуть ссылку на объект, который унаследован от UnicastRemoteObject. 


  

Это сообщение отредактировал(а) MoonCat - 2.7.2006, 20:43


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
02077461
Дата 19.10.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 13.7.2005

Репутация: нет
Всего: 0



Цитата(Wowa @  30.6.2006,  13:32 Найти цитируемый пост)
на каждого клиента по отдельному Thread на сервере для чтения
 
я не понимаю -- зачем по треду на клиента? Почему не использовать один тред, который будет получать/идентифицировать сообщение и выдавать объекты с нужной инфонмацией?
Пожалуйста, объясните.
PM   Вверх
LSD
Дата 25.10.2006, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



Цитата(02077461 @  19.10.2006,  12:59 Найти цитируемый пост)
я не понимаю -- зачем по треду на клиента? Почему не использовать один тред, который будет получать/идентифицировать сообщение и выдавать объекты с нужной инфонмацией?

Так проще. Тред обслуживает только один сокет, т.е. читает данные до опупения.
Если будешь работать с одним тредом, то будет проблема в том, что например не все данные от клиента пришли. Значит надо или ждать пока дойдут оствашиеся, что неприемлимо поскольку остальные клиенты будут ждать, и вообще не факт что данные дойдут вообще. Или создавать временный буфер куда класть данные полученные частично, но тут свои заморочки.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
02077461
Дата 25.10.2006, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 13.7.2005

Репутация: нет
Всего: 0



Спасибо, понял, когда писал для себя примерчик. Действительно так проще, и полностью покрывает потребности небольшой сети.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0965 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.