powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / ConnectionPool для User-ов
11 сообщений из 11, страница 1 из 1
ConnectionPool для User-ов
    #33952399
tserega
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток!

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

Поискал по форуму, нашел вот тут:
/topic/248242#2210032

Там есть предложение использовать всего два потока на всех клиентов - один читает, другой пишет.

Есть ли где-нибудь более подробное описание такой схемы?

Я вот тут сделал вариант, как я это вижу. Насколько он корректен?

Тест для проверки всего:
Код: plaintext
\n public   class  TestPool {\n     public   static   void  main(String[] args)  throws  InterruptedException {\n         new  PoolingServer().start();\n\n        Thread.sleep( 1000 );\n\n         int  count =  2 ;\n\n         for  ( int  i =  0 ; i < count; i++) {\n             new  PoolingClient().start();\n        }\n    }\n}\n

Клиент:
Код: plaintext
\n import  java.util.Random;\n import  java.net.Socket;\n import  java.io.IOException;\n import  java.io.OutputStream;\n import  java.io.InputStream;\n\n public   class  PoolingClient  extends  Thread {\n\n     private   int  id;\n\n     public   void  run() {\n         try  {\n             final  Socket s =  new  Socket("localhost",  12345 );\n            Random random =  new  Random();\n            id = random.nextInt();\n            OutputStream os = s.getOutputStream();\n             final  InputStream is = s.getInputStream();\n\n             new  Thread() {\n                 public   void  run() {\n                     while  (true) {\n                         try  {\n                             int  i = is.read();\n                            System.out.println("client #" + id + ", " + i);\n                        }  catch  (IOException e) {\n                            e.printStackTrace();\n                        }\n                    }\n                }\n            }.start();\n\n             while  (true) {\n                os.write(id);\n                os.flush();\n                Thread.sleep(random.nextInt( 1000 ));\n            }\n        }  catch  (IOException e) {\n            e.printStackTrace();\n        }  catch  (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n

Сервер:
Код: plaintext
\n import  java.net.ServerSocket;\n import  java.net.Socket;\n import  java.io.IOException;\n import  java.io.InputStream;\n import  java.io.OutputStream;\n import  java.util.*;\n\n public   class  PoolingServer  extends  Thread {\n\n    HashMap<Socket, PooledUser> users =  new  HashMap<Socket, PooledUser>();\n\n     public   void  run() {\n         try  {\n             new  ReadingThread().start();\n             new  SendingThread().start();\n\n            ServerSocket sock =  new  ServerSocket( 12345 );\n             while  (true) {\n                Socket s = sock.accept();\n                PooledUser user =  new  PooledUser();\n                user.socket = s;\n                user.input = s.getInputStream();\n                user.output = s.getOutputStream();\n                 synchronized (users) {\n                    users.put(s, user);\n                }\n            }\n        }  catch  (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n     private   static   class  PooledUser {\n        Socket socket;\n        InputStream input;\n        OutputStream output;\n        Vector<Integer> replies =  new  Vector<Integer>();\n    }\n\n     private   class  ReadingThread  extends  Thread {\n\n         public   void  run() {\n             while  (true) {\n                 synchronized  (users) {\n                     for  (Iterator<PooledUser> it = users.values().iterator(); it.hasNext(); ) {\n                        PooledUser user = it.next();\n                        InputStream is = user.input;\n                         try  {\n                             if  (is.available() >  0 ) {\n                                 int  x = is.read();\n                                x = -x;\n                                user.replies.add(x);\n                                yield();\n                            }\n                        }  catch  (IOException e) {\n                            e.printStackTrace();\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n     private   class  SendingThread  extends  Thread {\n         public   void  run() {\n             while  (true) {\n                 synchronized  (users) {\n                     for  (Iterator<PooledUser> it = users.values().iterator(); it.hasNext(); ) {\n                        PooledUser user = it.next();\n                         if  (user.replies.size() >  0 ) {\n                             try  {\n                                user.output.write(user.replies.remove( 0 ));\n                                user.output.flush();\n                                yield();\n                            }  catch  (IOException e) {\n                                e.printStackTrace();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n

При любом случае нагрузка получается где-то 70-90% процессорного времени (процесс java.exe в Task manager-е). По профайлеру тоже вроде как все нормально...
Меня больше всего волнует то, что ReadingThread и SendingThread используют ВСЕ время системы...
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33952583
Satrac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А пул потоков не подходит?
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33952594
tserega
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что он реально даст?
Когда клиенты исчисляются сотнями или даже тысячами, то это ж все равно будет тысячи потоков...
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33952804
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tserega
Данный подход неплохо работает на сравнительно небольшом количестве пользователей (где-то до 50)


А ты не пробовал менять размер стека у серверного сокета:
Код: plaintext
1.
ServerSocket sock =  new  ServerSocket( 12345 ,  100 );

- по умолчанию он как раз 50 и твои соединения съели весь стек, увеличь его!
ну и конечно подумай получше об архитектуре приложения
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33953027
tserega
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kachalov tserega
Данный подход неплохо работает на сравнительно небольшом количестве пользователей (где-то до 50)


А ты не пробовал менять размер стека у серверного сокета:
Код: plaintext
1.
ServerSocket sock =  new  ServerSocket( 12345 ,  100 );

- по умолчанию он как раз 50 и твои соединения съели весь стек, увеличь его!

Но ведь это же не решает проблему кучи потоков...

Kachalov
ну и конечно подумай получше об архитектуре приложения
Вот и думаем над этим...
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33953393
Satrac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторА что он реально даст?
Когда клиенты исчисляются сотнями или даже тысячами, то это ж все равно будет тысячи потоков..
Ты ляжешь, если будешь создавать на каждого юзверя поток. Обмен данными идет непрерывно? Если нет, то пул event-driven потоков твое спасение.
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33953422
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
интересно зачем ТЫСЯЧАМ клиентов постоянное соединение?

игру чтоли пишите сетевую?
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33954443
tserega
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SatracОбмен данными идет непрерывно?
Да, непрерывно.

vfabrинтересно зачем ТЫСЯЧАМ клиентов постоянное соединение?

игру чтоли пишите сетевую?
Ну... это не так далеко от истины...
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33954598
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
IMHO В сетевой игре не обязательно держать соединение постоянно. Ну может его и желательно держать, но только в некоторых случаях, например, когда идет бой, а когда игрок перемещается то можно и без него.

Во всяком случае игровые серваки (в которых держится постоянное соединение если такие есть) это должны быть здоровые кластера которые между собой делят нагрузку, я так думаю 200-300 игроков на сервер. Соответственно 10-20 серваков.

Кстати например TimeZero одновременно играющих больше 3.5 тыс я ниразу не видел (естессно у них никакой коннект не держится).

А если будет всего 2 потока на ТЫСЯЧИ одновременных клиентов то посчитайте сколько времени будет максимальная задержка для игрока который попал в очередь последним.
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33954611
zest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смотри в сторону NIO и SocketChannel
...
Рейтинг: 0 / 0
ConnectionPool для User-ов
    #33955064
Satrac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторНу... это не так далеко от истины...
WOW? ;-) Либо нужен очень хороший сервер, либо другая логика.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / ConnectionPool для User-ов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]