Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Веб-программирование > Общее

Общее Веб-разработка в целом, идеи, проекты...

Ответ
 
Опции темы
Старый 31.10.2016, 07:16   #1
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Правильная организация Server<-> client

Как правильно реализовать обмен данных между сервером и клиентом при условии, что клиентов несколько (4 штуки максимум) и сервер постоянно что-то должен выполнять (т.е не должно быть блокировки)?

Само детище на C# и как я понял в тренде сейчас async/await ,но я не знаю как это использовать, a не круто делать так:
* Поток регистрации клиентов
* Поток логики
* По-потоку на каждого клиента

Еще желательно, что бы CPU-frendly это все было, так как десктопная приложенька, которая предполагается, будет работать фоном.

Тыкните в правильное направление.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 31.10.2016, 09:00   #2
Andvrok
Бывалый
 
Регистрация: 26.07.2009
Сообщений: 746
Написано 343 полезных сообщений
(для 959 пользователей)
Ответ: Правильная организация Server<-> client

Почему «не круто» делать через потоки?
__________________
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
impersonalis (31.10.2016)
Старый 31.10.2016, 10:13   #3
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от Andvrok Посмотреть сообщение
Почему «не круто» делать через потоки?
Процессорное время.


Какого фига все, что после обведенного красным НИКОГДА не выполняется??
Я ради эксперимента даже использовал обычный метод, и все равно, даже в дебагере дальше этого места не идет, и главное нету исключений вообще никак.

Асинхронная запись работает, а асинхронное/синхронное чтение НЕТ!
__________________
Сайт: http://iexpo.ml

Последний раз редактировалось RegIon, 31.10.2016 в 11:19.
(Offline)
 
Ответить с цитированием
Старый 31.10.2016, 11:48   #4
Andvrok
Бывалый
 
Регистрация: 26.07.2009
Сообщений: 746
Написано 343 полезных сообщений
(для 959 пользователей)
Ответ: Правильная организация Server<-> client

Я не особо по асинхронности, но сейчас сделал по примеру в мсдн и всё работает.
__________________
(Offline)
 
Ответить с цитированием
Старый 31.10.2016, 12:09   #5
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от Andvrok Посмотреть сообщение
Я не особо по асинхронности, но сейчас сделал по примеру в мсдн и всё работает.


У меня TcpClient.Stream, писаться в него пишется, а читаться - нифига.

__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 31.10.2016, 16:11   #6
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Оказалость, что если указать локальным хостом для TcpListener "127.0.0.1", то можно словить забавный баг - до него нельзя достучаться по IP локальной сети, у меня это 192.168.1.3, а если получается, то только сервер не может из него читать - только писать.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
St_AnGer (31.10.2016)
Старый 31.10.2016, 17:44   #7
h1dd3n
Бывалый
 
Аватар для h1dd3n
 
Регистрация: 19.06.2008
Сообщений: 677
Написано 263 полезных сообщений
(для 448 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от Andvrok Посмотреть сообщение
Почему «не круто» делать через потоки?
Очевидно что нормальный сервер многопоточный (иначе не будут использоваться все процессоры).
Однако создавать по потоку на каждого клиента - это самый плохой способ. Большую часть времени потоки будут тупо ничего не делать а ждать данных от i/o. В итоге будут жрать память и жрать процессорное время. Короче херовая масштабируемость.
Впрочем, если там 3-4 клиента то разница вообще незначительная.
Оказалость, что если указать локальным хостом для TcpListener "127.0.0.1", то можно словить забавный баг - до него нельзя достучаться по IP локальной сети, у меня это 192.168.1.3, а если получается, то только сервер не может из него читать - только писать.
Много раз писал небольшие локальные серваки на дотнете, ни разу такого не наблюдал. Брандмауэр/антивирус? Версия фреймворка?
__________________
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо h1dd3n за это полезное сообщение:
Andvrok (31.10.2016), impersonalis (01.11.2016)
Старый 31.10.2016, 20:18   #8
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Правильная организация Server<-> client

Чтение с клиентов данных и их подготовка (десериализация) к употреблению в игровом цикле. Это одним потоком с использованием async/await.

Игровой цикл в своём потоке, выполняется фиксированное раз в секунду. Чем выше частота логики, тем лучше (обычно), но и CPU стоимость будет выше.

Цикл рассылки данных, может быть по той же частоте как и игровая логика, а может быть реже в два раза. Зависит от ситуации. Но должен выполнятся также конкретное раз в секунду, и сразу же после игрового цикла. Собирает данные с игрового цикла, и рассылает всем клиентам используя async/await.

Использовать поток на каждого клиента - не масштабируется, и жрёт много RAM'а, также усложняет всю логику синхронизации данных между потоками.
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
Andvrok (31.10.2016), impersonalis (01.11.2016), Phantom (31.10.2016)
Старый 31.10.2016, 20:42   #9
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от h1dd3n Посмотреть сообщение
Много раз писал небольшие локальные серваки на дотнете, ни разу такого не наблюдал. Брандмауэр/антивирус? Версия фреймворка?
.net 4.6, брадмауэр спроисл разрешение - я дал.

Сменил IP на 0.0.0.0 вместо 127.0.0.1 - все работает.

Чтение с клиентов данных и их подготовка (десериализация) к употреблению в игровом цикле. Это одним потоком с использованием async/await.
Тут небольшая проблема.
Пусть у нас 4 клиента, шаг опроса -10 ms , сделаем до каждого асинхронный запрос на чтение данных, а придет он только через 10 + ping.

У меня сейчас Один поток логики с Thread.Sleep(10), который асинхронно обрабатывает подключение, которое асинхронно запускает цикл чтения у подключившегося клиента (кароче, поток фактически запускает). Это асинхронное чтение десериализует и вызывает делигат с получеными данными, на который подписан поток логики.

Вроде работает, только не могу с входного потока прочитать, не закрыв его.
Вернее, у меня клиент на Java. Хоть очищай, хоть не очищай выходой поток - пока его не закроешь (что нельяз, так как закроется сокет) - данные не уйдут
в c# это решилось Writer.autoFlush, а у BufferedWriter в Java такого нет и flush не помогает.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 31.10.2016, 21:30   #10
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Правильная организация Server<-> client

Я с Java работал лет 6 назад, и как раз работал с потоками и веб сокетами, там есть возможность опрашивать есть ли в наличии для чтения данные из сокета, и затем получать если есть, совмещаешь это с асинком и будет ок.

Гугли.
(Offline)
 
Ответить с цитированием
Старый 01.11.2016, 06:50   #11
Nex
Гигант индустрии
 
Аватар для Nex
 
Регистрация: 13.09.2008
Сообщений: 2,888
Написано 1,183 полезных сообщений
(для 3,292 пользователей)
Ответ: Правильная организация Server<-> client

(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
RegIon (01.11.2016)
Старый 01.11.2016, 07:17   #12
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от Nex Посмотреть сообщение
4 подобных ролика посмотрел и в вкурил как это работает. Так же как в JS, только вызывается не калбек - а продолжается как Corotutine в Unity.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 01.11.2016, 09:01   #13
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 03.09.2005
Сообщений: 14,014
Написано 6,795 полезных сообщений
(для 20,920 пользователей)
Ответ: Правильная организация Server<-> client

Топикстартер, ты что - переделал первый пост? Когда я читал его первый раз, там была фраза, что мол, потоки плохо без особой мотивации - что и вызвало недоумение.

Вообще - солидарен с mok-иной архитектурой. Вроде ещё механизм "пул потоков" по теме может пригодиться, но я с ним не работал.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 01.11.2016, 09:10   #14
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,157
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Правильная организация Server<-> client

Сообщение от impersonalis Посмотреть сообщение
Топикстартер, ты что - переделал первый пост? Когда я читал его первый раз, там была фраза, что мол, потоки плохо без особой мотивации - что и вызвало недоумение.

Вообще - солидарен с mok-иной архитектурой. Вроде ещё механизм "пул потоков" по теме может пригодиться, но я с ним не работал.
Нет, не переделал . async/await - не потоки как таковые.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 01.11.2016, 17:21   #15
h1dd3n
Бывалый
 
Аватар для h1dd3n
 
Регистрация: 19.06.2008
Сообщений: 677
Написано 263 полезных сообщений
(для 448 пользователей)
Ответ: Правильная организация Server<-> client

Судя по всему в этой теме смешалось в кучу все: кони, люди, потоки, таски, async/await, threadpool...
  • Создавать потоки вручную (использовать класс Thread) в современном C#/.NET нужно только в 0.00001% случаях, и ситуация ТС под этот случай не подходит.
  • В C# нынче (и вообще-то уже довольно давно) оперируют тасками - Task, Task<T>. Таск это просто задача, сами по себе таски никакого отношения к потокам не имеют. Таски вообще совершенно отдельная от async/await фича.
  • Для того чтобы сервер нормально масштабировался хорошо бы чтобы потоки не блокировались и переиспользовались. Async/await к этому отношения не имеет. Асинхронные серверы были в дотнете ЕМНИП со 2.0 версии фреймворка - IAsyncResult паттерн.
  • Когда мы создаем таск (Task), то скорее всего (такое поведение по умолчанию), мы ставим эту задачу на выполнение шедулеру (TaskScheduler).
  • Шедулер по своему внутреннему алгоритму как-то выполняет задачи. Дефолтный шедулер использует ThreadPool. В дотнете есть и другие шедулеры. Можно также написать свой шедулер. Но это не понадобится (скорее всего).
  • Async/await - это просто синтаксический сахар C# (на уровне clr об async/await даже не нужно ничего знать). Самое главное понять что он никакой магии не делает.
  • Использовать Thread.Sleep(10) - гиблое дело. Надо использовать await Task.Delay(10). То есть пока мы ждем эти 10мс, поток может пойти и выполнить какую-нибудь работу.
  • При использовании TPL (таски, шедулер и Ко) совсем не обязательно что продолжение будет выполняться тем же потоком. То есть: есть 2 задачи - прочитать из 1 сокета, и обработать, и прочитать из 2 сокета и обработать. Предположим действие происходит следующим образом: поток A обрабатывает первую задачу, он доходит до чтения и дальше ничего делать не может пока данные не придут. Конечно он идет делать другую полезную задачу - обрабатывать задачу 2. Но пока он это делал в 1 задаче из i/o пришли данные и надо бы выполнение то продолжить, но т.к. поток А занят, этим займется поток Б (который возьмется из тредпула).
  • Пункт выше объясняет почему создавать потоки вручную - идиотизм. Может получиться так что: создали поток, внутри потока, где-то есть await. Значит все продолжение после await может быть выполнено потоком из тредпула. Получается что созданный вручную поток потерян навсегда и вообще не будет использоваться.

Тебе надо - создать таск который в бесконечном цикле принимает соединения. Когда принимаешь соединение создаешь таск с бесконечным циклом в котором принимаешь данные.
Далее есть 2 варианта - если у тебя архитектура запрос/ответ (ну как http примерно) то сразу же начинаешь обрабатывать. Если у тебя что-то типа реалтайм сервера, то ты полученные данные просто куда-то кладешь (в какое-то потокобезопасное хранилище). Нету никакого "шага" в виде 10мс на чтение. Читаешь сколько можешь.
Вот на обработку (если мы говорим о реалтайм сервере) уже может быть шаг предположим 8мс. Каждый раз в этом реалтайм цикле (а это тоже таск, не поток), ты берешь все данные из этого "потокобезопасного хранилища" и обрабатываешь их, потом снова уходишь в Task.Delay.
__________________
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Andvrok (01.11.2016)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 20:05.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com