Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WCF сервис не хочет рабоать 
:(
    Опции темы
HAL707
Дата 31.7.2009, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день.
В общем пишу я программу для удаленного взаимодействия с БД. Решил использовать WCF для такого случая и уже об этом пожалел. Куча ошибок в местах, где они быть не должны имхо...
Короче без лишних слов пример:
dll с сервисом такая:
Код

[ServiceContract]
    public interface IBidOfferContract
    {
        [OperationContract]
        DataTable GetData();
    }

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class MainModule : IWCFService, IBidOfferContract
    {
        static ServiceHost serviceHost;
        public void Start()
        {
            serviceHost = new ServiceHost(this);
            serviceHost.AddServiceEndpoint(typeof(IBidOfferContract), new NetTcpBinding(), @"net.tcp://localhost:6669/MessageService");
            serviceHost.Open();
        }

        public void Stop()
        {
            serviceHost.Close();
        }

        public string GetInfo()
        {
            return null;
        }

        public DataTable GetData()
        {
            return new DataTable();
        }
    }


Для тестирования использую консольное приложения в котором создаю клиента и сервера.

Код

static void Main(string[] args)
        {
            //Стартуем сервис (в списке он только 1)
            foreach (IWCFService service in wcfservices)
            {
                service.Start();
            }
             //Создаем клиента в отдельном потоке
            Thread cunsumerThread = new Thread(new ThreadStart(ServiceConsumer));
            cunsumerThread.Start();

            Console.ReadLine();
        }

static void ServiceConsumer()
        {
            var channelFactory = new ChannelFactory<IBidOfferContract>(new NetTcpBinding());
            var service = channelFactory.CreateChannel(new EndpointAddress(@"net.tcp://localhost:6669/MessageService"));
            DataTable t =  service.GetData();
        }

Получаем такой эксепшн:
Подключение к сокету было прервано. Возможно, это вызвано ошибкой обработки сообщения, превышением времени ожидания на удаленном узле или проблемой с выделенным сетевым ресурсом.

В иннер эксепшн:
Удаленный хост принудительно разорвал существующее подключение

Что за черт вообще? Что не так?

Я уж не говорю, что у ВЦФ есть такой прикол, что к нему из ВинФормс невозможно подключиться. Делал до этого сервис, тестил в винформс. Клиент не подключается с такой же ошибкой. Перенес на консоль (НИЧЕГО не менял) - все отлично работает...

Что за муто ваще такая??
(через ремотинг все отлично кстати соединяется)
PM MAIL   Вверх
mihryak
Дата 31.7.2009, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



обычно такая ошибка говорит о проблемах сериализации
и это - чуть ли единственная, на мой взгляд, проблема wcf, ошибку можно было бы и посимпатичнее выдавать
с другой стороны, это противоречило бы концепции Fault, в ней до пользователя не должны доходить исключения, раскрывающие техническую сторону сервиса.
на сервисе же ошибку можно поймать в первозданном виде, надо только слегка потрудиться

в общем, в твоём случае сериализция не проходит из-за "Cannot serialize the DataTable. DataTable name is not set."
чтобы иметь возможность отлавливать подобные ошибки, существует интерфейс IErrorHandler
добавь эти 2 класса
Код

    class LoggingErrorHandler : IErrorHandler
    {
        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
        }

        public bool HandleError(Exception error)
        {
            return false; // здесь можно ставить бряки, логировать и т.п.
        }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class LoggingServiceBehaviorAttribute : Attribute, IServiceBehavior
    {
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(
            ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
            {
                channelDispatcher.ErrorHandlers.Add(new LoggingErrorHandler());
            }
        }
    }
 
и выставь этот атрубут своему классу, реализующему контракт
Код

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    [LoggingServiceBehavior]
    public class MainModule : IBidOfferContract


Цитата(HAL707 @  31.7.2009,  15:32 Найти цитируемый пост)
у ВЦФ есть такой прикол, что к нему из ВинФормс невозможно подключиться

это не так


Это сообщение отредактировал(а) mihryak - 31.7.2009, 19:02
PM MAIL ICQ   Вверх
mihryak
Дата 1.8.2009, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



кстати, необязательно использовать именно дефолтовый DataContractSerializer
так, например, можно контракту указать использовать XmlSerializer
Код

    [ServiceContract]
    [XmlSerializerFormat]
    public interface IBidOfferContract

PM MAIL ICQ   Вверх
HAL707
Дата 3.8.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Насчет серализации - согласен. Поменял типы - все заработало.
Но с винформами все равно странности.
Не работает, если клиент и сервис в одной программе.

Код

[ServiceContract]
        public interface IBidOfferContract
        {
            [OperationContract]
            DateTime GetData();
        }

        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        [LoggingServiceBehavior]
        public class MainModule : IBidOfferContract
        {
            public string GetInfo()
            {
                return null;
            }

            public DateTime GetData()
            {
                return DateTime.Now;
            }
        }

private void button1_Click(object sender, EventArgs e)
        {
            var serviceHost = new ServiceHost(new MainModule());
            serviceHost.AddServiceEndpoint(typeof(IBidOfferContract), new NetTcpBinding(), @"net.tcp://localhost:6669/MessageService");
            serviceHost.Open();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var channelFactory = new ChannelFactory<IBidOfferContract>(new NetTcpBinding());
            var service = channelFactory.CreateChannel(new EndpointAddress(@"net.tcp://localhost:6669/MessageService"));
            DateTime t = service.GetData();
        }


Получаем простыню:
Во время операции запроса в net.tcp://localhost:6669/MessageService ответ не был получен в течение настроенного времени ожидания (00:01:00). Время, назначенное для выполнения этой операции, может быть составной частью более длинного тайм-аута.  Это может быть связано с тем, что служба продолжает обработать операцию, или с тем, что службе не удалось отправить ответное сообщение.

Как это побороть?

PM MAIL   Вверх
mihryak
Дата 3.8.2009, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



это происходит по причине одновременного использования одного синхронизационного контекта и сервисом, и UI, соотв. и возникает блокировка вызова
читай тут
там же указано и решение проблемы - выставить свойству UseSynchronizationContext атрибута ServiceBehavior в false
Код

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
    [LoggingServiceBehavior]
    public class MainModule : IBidOfferContract


использование WCF имеет множество нюансов и, на первый взгляд, несуразных проблем, да и вообще - не такая уж и тривиальная штука
но с появлением опыта его возможности не перестают удивлять
PM MAIL ICQ   Вверх
HAL707
Дата 4.8.2009, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо! Все понятно smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception.

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


 




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


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

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