65.9K
CodeProject 正在变化。 阅读更多。
Home

Wcf.js:从 Node.js 调用 WCF Web 服务

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2012年5月6日

CPOL

3分钟阅读

viewsIcon

85649

downloadIcon

4

从 Node 应用程序中调用现有 Web 服务。

引言

Node.js 正成为初创公司和企业开发者的绝佳选择。虽然 REST Web 服务是新的 Node 开发的首选,但也需要从 Node 应用程序中调用现有 Web 服务。在调用 WCF Web 服务时,这是一个挑战,因为 WCF 支持许多不容易生成的标准和协议。Wcf.js 是一个 Node.js 库,旨在简化此方案。

背景 

你可能要问的第一个问题是,为什么我们需要一个特殊的库来调用 SOAP Web 服务。毕竟,HTTP 在 Node.js 中是一流公民,我们可以简单地通过 HTTP 将 SOAP 发送到服务。但是,Web 服务可能支持诸如 Ws-Security 或 MTOM 之类的标准,而 Node 无法开箱即用地支持这些标准。实际上,这正是另一个项目 ws.js 解决的问题。

因此,如果我们有 ws.js,为什么还需要 wcf.js

这两个项目是互补的。虽然 wcf.js 没有在 ws.js 之上添加任何新的标准实现,但它模仿了 WCF API。这意味着用户可以使用其原生 API 访问 WCF,而无需学习新的范例。所有这些都是以纯 JavaScript 方式完成的!

使用代码 

1. 首先,你必须安装 Wcf.js 模块

npm install wcf.js

2. 现在编写你的代码:

var BasicHttpBinding = require('wcf.js').BasicHttpBinding
  , Proxy = require('wcf.js').Proxy
  , binding = new BasicHttpBinding(
        { SecurityMode: "TransportWithMessageCredential"
        , MessageClientCredentialType: "UserName"
        })
  , proxy = new Proxy(binding, "https://:7171/Service/clearUsername")
  , message =  "<Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'>" +
                 "<Header />" +
                   "<Body>" +
                     "<GetData xmlns='http://tempuri.org/'>" +
                       "<value>123</value>" +
                     "</GetData>" +
                    "</Body>" +
               "</Envelope>"
proxy.ClientCredentials.Username.Username = "yaron"
proxy.ClientCredentials.Username.Password = "1234"
proxy.send(message, "http://tempuri.org/IService/GetData", function(response, ctx) {
  console.log(response)
});     

如果这段代码看起来很熟悉,那么你是对的 - 它与 WCF API 相同。因此,你可以像使用 WCF 一样自由地创建绑定和行为。上面的例子在这行中初始化了一个 wcf basicHttpBinding:

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

然后它配置凭据

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

然后调用服务

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

与 WCF 完全一样!

自定义绑定示例

相同的方法可以帮助我们构建自定义绑定:

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, "https://: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)    
}); 

你应该注意这里如何在自定义绑定上定义通道

  binding = new CustomBinding(
        [ new MtomMessageEncodingBindingElement({MessageVersion: "Soap12WSAddressing10"}),
        , new HttpTransportBindingElement()
        ])  

你可以创建自己的通道并将它们放在管道中。这个具体例子使用了 mtom 通道。

为什么 MTOM 需要额外的工作?

上面的例子使用了 MTOM 通道。这就是为什么我们需要通过指定 base64 元素路径来做更多的工作:

proxy.addAttachment("//*[local-name(.)='File1']", "me.jpg"); 

我们不需要在 WCF 中这样做,那么为什么 Wcf.js 需要这样做?

让我们看看这个 soap 元素:

<a:File1 />  

如果未使用 MTOM,那么这部分将填充 me.jpg 的 base64 表示形式

 <a:File1>PS2Kqw23A2A98...</a:File1> 

我们需要告诉 MTOM 通道获取此内容并将其作为二进制有效负载放在消息之外。那么为什么 WCF 不需要我们告诉它这些信息呢? WCF 是一个完整的 soap 堆栈,它也基于 WSDL 生成代理。当 WCF 生成 File1 参数时,它将其标记为 MTOM 转换的候选对象。因此,Wcf 从 Wsdl 获取了此信息。由于 Wcf.js 是一个纯 ws-* 堆栈(而不是 soap 堆栈),因此它无法访问 wsdl,我们需要提供此信息。

支持的绑定

Wcf.js 目前支持一个子集

  • BasicHttpBinding
  • WSHttpBinding
  • CustomBinding

当前的子集包括

  • MTOM / 文本编码
  • WS-Addressing(所有版本)
  • 传输安全(SSL)
  • 带有消息凭据(用户名)的传输

Ws.js 的未来

Wcf.js 是 Node.js 的 WCF 的纯 JavaScript 实现。

Wcf.js 是一个不断发展的框架。对于未来版本,我计划添加更多绑定支持,如 net.tcp 和 WsHttpBinding 中的专有安全协商。如果你有任何特殊要求,请从我的博客发送电子邮件给我。如果你想提供帮助,请随意在 github 上 fork Wcf.js - 这是发展 Wcf.js 的最快方式。

更多信息

查看项目 github 页面

查看我的博客

查看我的 Twitter

我的博客给我发电子邮件

© . All rights reserved.