1

所以我在一段代码中有 100 个不同的地方出错了。我最近从 Apache 和 PHP 切换到 Node.js。我有一段特定的代码,它只是复制它收到的请求。基本上,我的 Web 应用程序向我的服务器(PHP 或 Node.js)发布一个 JSON 请求,然后服务器向我的 Apache Camel 配置发送完全相同的请求。在 PHP 中,这非常有效。切换到 Node.js 时,我收到来自 Apache Camel 的错误。

具体来说,我有一段代码几乎瞬间发送了两次完全相同的请求(我知道如何修复它,请耐心等待)。在 PHP 中,这段代码可以正常工作。在 Node.js 中,第一个请求工作正常,但第二个请求失败。Apache Camel 第二次收到一个空主体的请求。老实说,我 100% 无能为力。

这里到底出了什么问题?逻辑告诉我,如果它适用于 PHP 而不是 Node(相同的 Camel 代码),那么它一定是 Node.js 的问题。但为了以防万一,我不得不提到 Camel,因为 Camel 有时会对请求做一些奇怪的事情。

我将在下面发布我的代码,也许您会看到一个问题。我已经为此工作了 3 天(打开和关闭),还没有发现问题。另外,请记住,我几天前才开始使用 node。

PHP

<?php
    require_once("globals.php");

    //There's nested JSON here so I could include the destination address
    $request = file_get_contents('php://input');
    $json = json_decode($request);
    $urlid = $json->{"urlid"};
    $json = $json->{"data"};

    if (session_start() === FALSE)
    {
        echo "{ \"postsuccess\": false, \"error\": -1 }";
        return;
    }

    if(!isset($_SESSION["username"]) ||
            !isset($_SESSION["expirationdate"]) ||
            !isset($_SESSION["securitytoken"]) ||
            $_SESSION["expirationdate"] <= time())
    {
        echo "{ \"postsuccess\": false, \"error\": -2 }";
        return;
    }

    if(strtolower($_SESSION["username"]) != strtolower($_COOKIE["UserNameCookie"]))
    {
        echo "{ \"postsuccess\": false, \"error\": -3 }";
        return;
    }

    $json->{"securitytoken"} = strtolower($_SESSION["securitytoken"]);
    $json->{"username"} = strtolower($_SESSION["username"]);
    $request = json_encode($json);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $URL[$urlid]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/plain; charset=utf-8"));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);

    $data = curl_exec($ch);
    curl_close($ch);

    echo $data;
?>

Node.js(打字稿)

function handler(request: ExpressServerRequest, response: ExpressServerResponse) {
    try {
        var json = (request.body || JSON.parse(request.rawBody));
        var security_token = request.cookies.get(global.security_token_cookie, {signed: true});
        var username = request.cookies.get(global.username_cookie, {signed: true});
        var urlid = json.urlid;
        json = json.data;

        if (!security_token || !username) {
            response.send({postsuccess: false, error: -2});
            return;
        }

        json.securitytoken = security_token;
        json.username = username;

        var callback = function(data) {
            response.json(data);
        };

        db.databaseRequest(urlid, json, callback);
    } catch (e) {
        console.error(e.stack);
        response.send({postsuccess: false, error: -1});
    }
}

//Was in a different module
function databaseRequest(url: number, data: any, callback: (any) => void) {
    try {
        var json = JSON.stringify(data);

        var headers = {
            "Content-Type": "application/json",
            "Content-Length": json.length
        };

        var options = {
            host: db_host,
            port: db_port,
            path: url_locations[url],
            headers: headers,
            method: "POST"
        };

        var request = http.request(options, function(response) {
            response.setEncoding("utf8");

            var returnData = "";

            response.on("data", function(d) {
                returnData += d;
            });

            response.on("end", function() {
                if (returnData) {
                    callback(JSON.parse(returnData));
                } else {
                    callback(null);
                }
            });
        });

        request.on("error", function(e) {
            console.error("Error posting database request:");
            console.error("Location: " + url_locations[url]);
            console.error("Data: " + json);
            console.error("Error Event: " + e);
        });

        request.write(json);
        console.log("Sending: " + json + " to " + url_locations[url]);
        request.end();
    } catch (e) {
        console.error(e.stack);
        request.end();
        callback({ "dberror" : true });
    }
}
4

1 回答 1

5

编辑:

我将保持更新,但老实说,我怀疑除了我之外的任何人都会遇到这个问题。:/

我找到了问题的根源。原来是并发问题。PHP 以线性方式提交请求,而 Node.js 是非阻塞的,因此它会在其他请求返回之前发送请求。本质上,我笨到可以将状态信息存储在处理器中。我的路线看起来像这样:

from("jetty:http://foo").process(new WorkProcessor()).to("direct:foo2");

我最初的想法是“好的,WorkProcessor每次触发路由时都会创建一个新的,因此每条消息都有自己的小沙箱”。不幸的是,事实并非如此,它只创建一次。我不知道为什么我会这么想,但我确实这么想。:(

所以我通过不在处理器实例中存储信息来解决这个问题。它使我的代码更长一点,但它解决了我的问题。

于 2013-04-08T03:02:14.207 回答