Node.js NET连接分块的XML数据

时间:2015-11-13 18:15:52

标签: xml node.js sockets soap

我通过Node中的NET套接字接收XML / SOAP。更大的SOAP响应被分块,所以我需要在将SOAP信封传递给XML解析器之前连接SOAP信封。

这是迄今为止的尝试

CLIPS> (run)
data 1
data FALSE
data FALSE
data FALSE
data FALSE
data FALSE
CLIPS> 

传入的数据看起来像(这些是小响应)

//client.net.setEncoding('utf8');
var data = '';
client.net.on('data', function(response) {
    var read = response.toString();
    console.log("READING == "+read);
    if (read.substr(read.length-15) === "</env:Envelope>") {
        if(data.length > 0) {
            /* soap envelope is finally complete, pass to xml parser */
            parser.parseString(data += response);
            data = '';
        }
        /* soap envelope is complete, pass to xml parser */
        parser.parseString(response);
    } else {
        /* not soap response */
        if (read.substr(0, 4) === "HTTP") return;
        /* add chunck to data */
        data += response;
    }
});

当信封不完整时,我正在合并这些块。

这似乎几乎可以工作,除了解析器开始抛出错误。

READING == HTTP/1.1 200 OK
Content-Type:application/soap+xml; charset="utf-8"
Content-Length:644


READING == <?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"><env:Header><n:Response x
mlns:n="http://www.example.com/" env:role="http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver" env:mustUnderst
and="true">SetTrackingFrequency</n:Response></env:Header><env:Body><n:ResponseSetTrackingFrequency xmlns:n="http://www.example.com/ipr
s/gps/soap"><n:Status>none</n:Status><n:ApplicationID>18</n:ApplicationID><n:RequestID>0</n:RequestID><n:FrequencySecs>0</n:FrequencySecs><n
:ExpirationSecs>0</n:ExpirationSecs></n:ResponseSetTrackingFrequency></env:Body></env:Envelope>

修改 - 更多信息

此代码给出错误,但是传递相同的响应?

error: uncaughtException: Text data outside of root node.

此代码没有错误

client.net.on('data', function(response) {
    var read = response.toString();
    if (read.substr(read.length-15) === "</env:Envelope>") {
        parser.parseString(response);
        return;
    }
}

完整错误:

client.net.on('data', function(response) {
        parser.parseString(response);
        return;
}

1 个答案:

答案 0 :(得分:0)

一种方法是通过寻找结束模式而不是使用开头,基本上是:

  • 每次收到缓冲区中的数据
  • 每次将数据附加到缓冲区,检查更新缓冲区中的结束模式
  • 只要在缓冲区中找到结束模式:
    • 从开始到第一个结束模式切一个片段,这是你的画面!
    • 继续并解析/处理该帧。务必将其从缓冲区中删除。
    • 如果缓冲区仍然包含结束模式,则继续砍掉缓冲区,否则让它生长

这就是全部!

var textBuffer = '';
var parseFrame = function (str){};

function processChunk (chunk) {
  var segments, frame;
  var startChar = String.fromCharCode(1);
  var endChar = String.fromCharCode(0);

  // having no endChar will skip the loop,
  // but we still save the chunk
  textBuffer += chunk;

  while (textBuffer && textBuffer.indexOf(endChar) !== -1) {
    // use endChar in lieu of startChar so we don’t
    // miss a chunk without beginning
    segments = textBuffer.split(endChar);

    // first chunk we extract may or may not have a startChar
    // replace() will have no effect if startChar is absent
    frame = segments.shift().replace(startChar, '');

    // if join() results in '', endChar won’t be found,
    // and we will get out of loop
    textBuffer = segments.join(endChar);

    // beware: it is possible that the frame
    // is incomplete if we *never* got the startChar,
    // the next chunks will be OK though
    try { parseFrame(frame); }
    catch (err) { console.log(err); }
  }
}