![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| V0fka |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
Привет!
Что нужно сделать. На сервере крутится программа, которая принимает входящие подключения от клиентов и при возникновении определенного события - отсылает им сообщения. Клиенты принимают сообщения и как-то реагируют. Клиентов планируется на данном этапе порядка 100. 1) Сервер: Сервер был сделан с помощью класса TcpListener. Далее в бесконечном цикле вызывается его метод AcceptTcpClient() и после полученный TcpClient добавляется в коллекцию clients. Это происходит не в основном потоке. Для отправки сообщений в цикле обходится коллекция clients и для каждого элемента выполняется io = client.GetStream() и потом io.Write(...); 2) Клиент: Используется класс Socket. В бесконечном цикле выполняется метод Receive и тут же эти данные обрабатываются и выполняются какие-то действия. Это происходит не в основном потоке. ///////////////// Я не особо шарю с C#, поэтому хотелось бы получить совет от людей, которые шарят, правильно ли выбрано направление для решения этой задачи: 1) Те ли классы я использую для сервера и клиента? 2) Если одновременно к серверу будет подключаться несколько клиентов, то используя в бесконечном цикле AcceptTcpClient() - я не пропущу никого из них? 3) Правильно ли на клиенте я "слушаю" сообщения? Меня смущает бесконечный цик там. Возможно это так делают, просто хочу узнать. Если же нет, то подскажите, пожалуйста, как надо. На данном этапе в детали не вдаюсь, т.к. вопросов тысяча. Просто хочу узнать правильное направление, чтобы когда уже будет виден финиш не обломиться из-за того, что в начале что-то не так было сделано. Спасибо! Это сообщение отредактировал(а) V0fka - 15.2.2014, 17:39 |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
можно и эти. Кстати есть класс TcpClient раз уж пошла речь..
если не будете долго тупить в "добавлении клиентов в очередь" то не должны бы... вообще можно использовать асинхронное API, но если не критично то можно крутить и цикл. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| V0fka |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
А какое преимущество TcpClient-а, в данном случае, будет?
Ясно, спасибо!
Правильно я вас понял, асинхронно - это, например, так: http://cyber-blog.klan-hub.ru/2010/08/28/а...етами-в-c-шарп/ ? Если да, то у меня здесь появилась проблемка. В классе Server я подключенных клиентов собираю в коллекцию:
и у меня возникает ошибка, как здесь: http://forum.vingrad.ru/forum/topic-336459.html: Для нестатического поля, метода или свойства "System.Windows.Threading.Dispatcher.Invoke(System.Delegate, params object[])" требуется ссылка на объект. Я её решил, передавая экземпляр Dispatcher в объект класса Server и соответственно вызываю Invoke через этот переданный диспатчер. Но, как всегда, есть сомнения насчет применения такого подхода. Хотелось бы получить "благословение" либо пинок в нужную сторону от знающих Это сообщение отредактировал(а) V0fka - 19.2.2014, 12:27 |
||||||
|
|||||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
а зачем связывать очередь с UI ?!
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| V0fka |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
Сервер - это WPF приложение. На форме есть ListView, к которому биндится очередь и видно кто подключен сейчас.
Это сообщение отредактировал(а) V0fka - 19.2.2014, 16:38 |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
и чО? Очередь просто должна уметь уведомлять подписчиком что что-то поменялось, а те уже в своих обработчиках должны решать как на эти действия реагировать - плохая идея добавлять данные в UI потоке. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| V0fka |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
Я по вашему совету переделал сервер и клиент с использованием асинхронных методов. Конкретно сервер работает через AcceptAsync(...). И в результате когда хочу в коллекцию (а это ObservableCollection) добавить элемент, то Visual Studio говорит, что "нельзя добавить из этого потока" (ошибка не дословная, но я думаю, вы поняли что это). Тогда я нагуглил, что нужно добавлять через Dispatcher.Invoke. Попрбовал, но получил ошибку, которую выше озвчучил. После этого сделал так, как написал. Можете пример какой-то привести, как это на примере WPF делается? |
|||
|
||||
| V0fka |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
По ходу разбирательств возник новый вопрос. Есть на сервере коллекция подключенных клиентов. В цикле обхожу её и методом Send хочу отправить сообщение. Все классно работает, если клиент подключен. Но если он отключен, то сервер виснет. Начал искать решения:
1) Установил на сервере в Socket.SendTimeout = 1, сделал через try catch отправку и если код попадает в catch - то клиент из коллекции удаляется. Подскажите, можно ли так делать, если планируется около 100 подключенных клиентов? 2) Обхожу коллекцию. Проверяю статус клиента IsConnected. Если IsConnected = false, то удаляю элемент из коллекции, если true, то отправляю сообщение. Но тут я заметил, что между проверкой и отправкой сообщения этот статус может поменяться и получается, что в момент Send клиента уже нету. Вопрос: как правильно проверять активных клиентов, чтобы им дошли сообщения? Это сообщение отредактировал(а) V0fka - 21.2.2014, 11:23 |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
для .net 4.5 имеется BindingOperations.EnableCollectionSynchronization, а для других версий можно написать свою коллекцию же, с маршалингом вызовов callback делегатов в нужном SyncronizationContext-е. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| V0fka |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 5.11.2006 Где: Украина Репутация: нет Всего: нет |
jonie, очередной раз я вам признателен за ответ, но что делать с BindingOperations.EnableCollectionSynchronization я в упор не пойму. Был бы очень признателен за примеры кода (псевдокода).
|
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | .NET для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |