Статьи

WCF и Node.js, так счастливы вместе

(получите wcf.js  на github !)

Посмотрите на следующий код:


var binding = new WSHttpBinding(
      { MessageEncoding: "Mtom"
      , SecurityMode:"TransportWithMessageCredential"
      })
   , proxy = new Proxy(binding)    

proxy.ClientCredentials.Username.Username = "yaron";
proxy.ClientCredentials.Username.Password = "1234";

proxy.send(message, function(response) {
  console.log(response)
});

Вы видите что-нибудь … особенное? Ну, c # уже имеет ключевое слово «var» начиная с версии 3.0, так что, может быть, это какой-то диалект ac # -ish? Или, может быть, это CTP для javascript в качестве языка CLR? Или что-то связанное с
лазурным sdk для node.js ?

Не за что. Это фрагмент из
wcf.js — чистого javascript-модуля node.js, который обеспечивает совместную работу wcf и node.js!

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

веб-API WCF, веб-API

ASP.NET очень просто. Также легко, если вы можете добавить базовую http-привязку к сервису Wcf, и немного больше работы, если вы планируете использовать
маршрутизатор wcf, чтобы сделать протокол моста.
Wcf.js — это библиотека, цель которой — предоставить опыт разработки на чистом javascript для таких сценариев.

Обратите внимание, что создание новых сервисов на базе node.js на основе ws- * не является целью этого проекта. Оставляя в стороне все религиозные войны, Soap — это не «путь узлов», поэтому вам следует придерживаться Rest, где вы получите хорошую поддержку языков (json) и встроенные библиотеки.

«Здравствуйте, Wcf … from node»

Вы ближе, чем вы думаете, чтобы использовать свой первый Wcf-сервис node.js:

1. Создайте новый веб-сайт wcf в VS и назовите его «Wcf2Node». Если вы используете .Net 4, то BasicHttpBinding используется по умолчанию, в противном случае в файле web.config замените WsHttp на BasicHttp. Не нужно развертывать, просто запустите службу в VS, используя F5.

2. Создайте в любом месте папку на стороне узла и в командной строке введите его корень и выполните:

$> npm install wcf.js

3. В этой же папке создайте test.js:

var BasicHttpBinding = require('wcf.js').BasicHttpBinding
  , Proxy = require('wcf.js').Proxy
  , binding = new BasicHttpBinding()
  , proxy = new Proxy(binding, " http://localhost:12/Wcf2Node/Service.svc")
  , message = '<Envelope xmlns=' +
            '"http://schemas.xmlsoap.org/soap/envelope/">' +
                 '<Header />' +
                   '<Body>' +
                     '<GetData xmlns="http://tempuri.org/">' +
                       '<value>123</value>' +
                     '</GetData>' +
                    '</Body>' +
               '</Envelope>'

proxy.send(message, "http://tempuri.org/IService/GetData", function(response, ctx) {
  console.log(response)
});

4. В test.js измените порт 12 (не спрашивайте …) на порт, на котором работает ваша служба.

5.  Теперь мы можем выполнить узел:

$> node test.js

6. Теперь вы должны увидеть выходное мыло на консоли.

Конечно, этот образец не очень интересен, и вам лучше отправить сырое мыло, используя
запрос . Давайте посмотрим что-нибудь более интересное. Если ваша служба использует токен ssl + username (транспорт с учетными данными сообщения), конфигурация может выглядеть следующим образом:

<wsHttpBinding>
    <binding name="NewBinding0">
        <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" />
        </security>
    </binding>
</wsHttpBinding>

Следующие модификации предыдущего примера позволят использовать его из узла:

...
binding = new WSHttpBinding(
        { SecurityMode: "TransportWithMessageCredential"
        , MessageClientCredentialType: "UserName"
        })
...

proxy.ClientCredentials.Username.Username = "yaron";
proxy.ClientCredentials.Username.Password = "1234";
proxy.send(...)

А вот и проволочное мыло:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<Header>
  <o:Security>
    <u:Timestamp>
      <u:Created>2012-02-26T11:03:40Z</u:Created>
      <u:Expires>2012-02-26T11:08:40Z</u:Expires>
    </u:Timestamp>
    <o:UsernameToken>
      <o:Username>yaron</o:Username>
      <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">1234</o:Password>
    </o:UsernameToken>
  </o:Security>
</Header>

<Body>
  <EchoString xmlns="http://tempuri.org/">
    <s>123</s>
  </EchoString>
</Body>

Если вы используете Mtom, посмотрите этот код:

(форматирование здесь немного утомительно из-за моего макета блога — в github он выглядит намного лучше
!)

var CustomBinding = require('wcf.js').CustomBinding

  , MtomMessageEncodingBindingElement = require('wcf.js').MtomMessageEncodingBindingElement

  , HttpTransportBindingElement = require('wcf.js').HttpTransportBindingElement

  , Proxy = require('wcf.js').Proxy
  , fs = require('fs')
  , binding = new CustomBinding(
        [ new MtomMessageEncodingBindingElement({MessageVersion: "Soap12WSAddressing10"}),
        , new HttpTransportBindingElement()
        ])

  , proxy = new Proxy(binding, "http://localhost:7171/Service/mtom")
  , message = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
                '<s:Header />' +
                  '<s:Body>' +
                    '<EchoFiles xmlns="http://tempuri.org/">' +
                      '<value xmlns:a="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' +
                        '<a:File1 />' +                   
                      '</value>' +
                    '</EchoFiles>' +
                  '</s:Body>' +
              '</s:Envelope>'
proxy.addAttachment("//*[local-name(.)='File1']", "me.jpg");
proxy.send(message, "http://tempuri.org/IService/EchoFiles", function(response, ctx) {
  var file = proxy.getAttachment("//*[local-name(.)='File1']")
  fs.writeFileSync("result.jpg", file)    
});

Mtom немного сложнее, так как wcf.js должен знать, какие узлы являются двоичными. Использование простого xpath может помочь вам достичь этого.
Очищение

рук с помощью Soap

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

Если вы будете использовать необработанные запросы и ответы мыла, вам понадобится хорошая библиотека xml. И хотя узел имеет множество библиотек dom / xpath, они не подходят для Windows. Мой следующий пост будет о хорошем совпадении здесь.

Поддерживаемые стандарты

Wcf реализует многие стандарты ws- * и даже больше через собственные расширения. Первая версия wcf.js поддерживает следующее:

  • MTOM
  • WS-Security (только токен имени пользователя)
  • WS-адресация (все версии)
  • HTTP (S)

    Поддерживаемая привязка:

  • BasicHttpBinding
  • WsHttpBinding
  • CustomBinding

    Что вы хотите увидеть дальше? Дайте мне знать .

    Получить код
    Wcf.js размещается в GitHub, и каждый может внести свой вклад в исправления и исправления, если это необходимо.
    Wcf.js работает на ws.js , фактической реализации стандартов, о которой я расскажу в следующем посте.