Выбор кодировщика сообщений
В этой статье рассматриваются критерии выбора среди кодировщиков сообщений, включенных в Windows Communication Foundation (WCF): двоичный, текстовый и механизм оптимизации передачи сообщений (MTOM).
В WCF вы указываете, как передавать данные по сети между конечными точками с помощью привязки, состоящей из последовательности элементов привязки. Кодировщик сообщений - это элемент привязки кодирования сообщений в стеке привязки. В привязку входят необязательные элементы привязки протокола, такие как элемент привязки безопасности или элемент привязки надежного обмена сообщениями, обязательный элемент привязки кодирования сообщений, и обязательный элемент привязки транспорта.
Элемент привязки кодирования сообщений находится под необязательными элементами привязки протокола и над обязательным элементом привязки транспорта. На стороне отправки кодировщик сообщений сериализует исходящий объект Message и передает его транспорту. На стороне приема кодировщик сообщений получает сериализованную форму объекта Message от транспорта и передает его на более высокий уровень протоколов, если он имеется, или приложению в противном случае.
При соединении с существующим клиентом или сервером возможно, что выбирать кодировщик не придется: кодировать сообщения необходимо способом, которого ожидает другая сторона. Однако если вы пишете службу WCF, вы можете предоставлять свою службу через несколько конечных точек, каждый из которых использует разные кодировки сообщений. Это позволяет клиентам выбирать оптимальный способ кодирования для взаимодействия со службой через оптимальную для них конечную точку, т. е. клиентам предоставляется возможность выбирать способ кодирования, лучше всего им подходящий. Использование нескольких конечных точек также позволяет сочетать преимущества разных способов кодирования сообщений с другими элементами привязки.
Кодировщики, предоставляемые системой
WCF включает три кодировщика сообщений, которые представлены следующими тремя классами:
TextMessageEncodingBindingElement - текстовый кодировщик сообщений - поддерживает и кодирование в простой XML, и кодирование SOAP. Режим кодирования в простой XML текстового кодировщика называется "plain old XML" (POX), что позволяет отличить его от текстового кодирования SOAP. Чтобы включить POX, присвойте свойству MessageVersion значение None. Используйте кодировщик текстовых сообщений для взаимодействия с конечными точками, отличными от WCF.
BinaryMessageEncodingBindingElement, кодировщик двоичных сообщений, использует компактный двоичный формат и оптимизирован для обмена данными WCF с WCF и поэтому не совместим. Это также наиболее производительный кодировщик всех кодировщиков WCF.
MtomMessageEncodingBindingElement - элемент привязки - задает способ кодирования и управления версиями для сообщений, использующих кодирование MTOM. MTOM - это эффективный способ передачи двоичных данных в сообщениях WCF. Кодировщик MTOM пытается сохранить баланс между эффективностью и совместимостью. Кодирование MTOM передает большую часть XML-данных в текстовой форме, но оптимизирует большие блоки двоичных данных путем передачи их в исходном виде, без преобразования в текст. С точки зрения эффективности, среди кодировщиков WCF предоставляется MTOM между текстом (самым медленным) и двоичным (самым быстрым).
Выбор кодировщика сообщений
В следующей таблице приведены факторы, чаще всего влияющие на выбор кодировщика сообщений. Расположите эти факторы в соответствии с их приоритетом для данного приложения и выберите оптимальные кодировщики сообщений. Не забудьте принять во внимание все дополнительные факторы, не приведенные в этой таблице, а также пользовательские кодировщики сообщений, которые могут понадобиться в приложении.
Множитель | Description | Кодировщики, поддерживающие этот фактор |
---|---|---|
Поддерживаемые кодировки | TextMessageEncodingBindingElement и MtomMessageEncodingBindingElement поддерживает только кодировки UTF8 и UTF16 Юникод (big-endian и little-endian). Если требуются другие кодировки, такие как UTF7 или ASCII, необходимо использовать пользовательский кодировщик. Пример пользовательского кодировщика см. в разделе "Пользовательский кодировщик сообщений". | Текст |
Инспекция | Под проверкой понимается возможность анализа сообщений во время передачи. Текстовое кодирование (как с использованием SOAP, так и без) позволяет ряду приложений проверять и анализировать сообщения без использования специализированных инструментов. Использование безопасности передачи на уровне сообщения или транспорта влияет на возможность проверки сообщений. Конфиденциальность подразумевает защиту сообщения от анализа, а целостность - от изменения. | Текст |
Надежность | Надежность - это устойчивость кодировщика к ошибкам передачи. Надежность также может обеспечиваться на уровне сообщения, транспорта или приложения. Все стандартные кодировщики WCF предполагают, что другой уровень обеспечивает надежность. Способность кодировщика восстановиться после ошибки передачи весьма ограничена. | нет |
Простота | Под простотой понимается простота создания кодировщиков и декодеров по спецификации кодирования. В этом отношении особо предпочтительны текстовые способы кодирования, причем текстовое кодирование POX имеет дополнительное преимущество - не требует поддержки обработки SOAP. | Текстовый (POX) |
Размер | Способ кодирования определяет объем служебных данных, налагаемых на содержимое. Размер кодированных сообщений напрямую связан с максимальной пропускной способностью операций службы. Двоичные способы обычно обеспечивают более компактное кодирование, чем текстовые. Когда размер сообщений имеет большое значение, следует рассмотреть также сжатие содержимого сообщений при кодировании. При этом следует помнить, что сжатие увеличивает вычислительные затраты как на стороне отправки, так и на стороне приема сообщений. | Binary |
Потоковая передача | Потоковая передача позволяет приложениям начинать обработку сообщения до получения всего сообщения. Эффективное использование потоковой передачи требует, чтобы важные данные содержались в начале сообщения, т. е. получающему приложению не нужно было дожидаться их поступления. Кроме того, приложения, использующие потоковую передачу, должны организовывать данные в сообщениях инкрементно, чтобы в содержимом не было зависимостей от последующих данных. Во многих случаях приходится идти на компромисс между потоковой передачей сообщения и минимальным размером передачи для содержимого. | нет |
Поддержка сторонних средств | Возможная поддержка включает разработку и диагностику. Сторонние разработчики делают большие вложения в библиотеки и наборы инструментов для обработки сообщений, кодированных в формат POX. | Текстовый (POX) |
Совместимость | Этот фактор относится к способности кодировщика WCF взаимодействовать со службами, отличными от WCF. | Текст MTOM (частично) |
Примечание. При использовании двоичного кодировщика использование параметра IgnoreWhitespace при создании XmlReader не оказывает никакого влияния. Например, если в операции службы выполняются следующие действия.
public void OperationContract(XElement input)
{
Console.WriteLine("{0}", input.Value);
int counter = 0;
var xreader = input.CreateReader();
var reader = XmlReader.Create(xreader, new XmlReaderSettings() { IgnoreWhitespace = true });
while (reader.Read())
{
counter++;
}
Console.WriteLine("Read {0} lines with reader", counter);
}
Параметр IgnoreWhitespace не учитывается.
Сжатие и двоичный кодировщик
Начиная с версии WCF 4.5, в двоичном кодировщике появилась поддержка сжатия. Это позволяет использовать алгоритм gzip/deflate для передачи сжатых сообщений из WCF-клиента и отправлять сжатые сообщения из резидентной службы WCF. Эта возможность обеспечивает сжатие сообщения для HTTP и TCP-каналов. WCF-службу, размещенную в IIS, можно настроить на повсеместную отправку сжатых ответов, выполнив соответствующую настройку узла IIS. Тип сжатия задается с помощью свойства BinaryMessageEncodingBindingElement.CompressionFormat. Свойству присваивается одно из значений перечисления System.ServiceModel.Channels.CompressionFormat.
Так как это свойство предоставляется только в двоичном файлеMessageEncodingBindingElement, вам потребуется создать пользовательскую привязку, например следующую, чтобы использовать эту функцию:
<customBinding>
<binding name="BinaryCompressionBinding">
<binaryMessageEncoding compressionFormat ="GZip" />
<httpTransport />
</binding>
</customBinding>
Клиент и служба должны согласиться отправлять и получать сжатые сообщения, поэтому свойство compressionFormat должно быть настроено на элемент binaryMessageEncoding как для клиента, так и службы. ПротоколException создается, если служба или клиент не настроены для сжатия, но другая сторона. Включение сжатия следует тщательно рассмотреть. Сжатие наиболее полезно в том случае, когда пропускная способность канала является узким местом в системе. В тех случаях, когда узким местом для производительности является ЦП, сжатие снизит пропускную способность системы. Для определения полезности применения сжатия для работы системе следует выполнить соответствующие тесты в симулированной среде выполнения.