2

Salesforce 最多可以在 1 条 SOAP 消息中发送 100 个请求。在发送这种类型的批量出站消息请求时,我的 PHP 脚本完成执行,但 SF 无法接受用于清除 Salesforce 端的消息队列的 ACK。查看出站消息日志(监控),我看到所有消息都处于挂起状态,传递失败原因为“java.net.SocketTimeoutException:读取超时”。如果我的脚本已完成执行,为什么会出现此错误?

我已经尝试了这些方法来增加我的服务器上的执行时间,因为我在 Salesforce 端没有访问权限:

  • 设置时间限制(0);// 在脚本中
  • max_execution_time = 360;每个脚本的最大执行时间,以秒为单位
  • 最大输入时间 = 360;每个脚本可能花费在解析请求数据上的最长时间
  • memory_limit = 32M ; 脚本可能消耗的最大内存量

我使用高设置只是为了测试。

关于为什么这导致将 ACK 传递回 Salesforce 失败的任何想法?

这是一些代码:这就是我为即将到来的 SOAP 请求接受和发送 ACK 文件的方式

$data = 'php://input';
$content = file_get_contents($data);

if($content) {
    respond('true');
} else {
    respond('false');
}

响应函数

function respond($tf) {
    $ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <Ack>$tf</Ack>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>
ACK;

    print trim($ACK); 
}

这些在我包含在将数据用于特定工作流的脚本中的通用脚本中。我可以处理大约 25 个请求(在 1 个 SOAP 响应中),但是一旦我处理完,我就会在 Salesforce 队列中收到超时错误。50 个请求通常需要我的 PHP 脚本 86.77 秒。

会不会是阿帕奇?php?

我还测试了仅接受 100 请求 SOAP 响应并仅接受并发送队列清除的 ACK,所以我知道它在我这边。

我在 apache 日志中没有显示错误,脚本运行良好。

我确实在 Salesforce 网站上找到了一些信息,但仍然没有运气。这是链接

我也在使用 PHP Toolkit 11(来自 Salesforce)。

其他对 SF 有很好帮助的论坛

感谢您对此的任何见解,--Phill

更新:

如果我收到传入的消息并打印响应,是否应该先发生这种情况,不管我之后是否做任何其他事情?还是等待我的过程完成然后打印响应?

更新#2:

好吧,我想我有问题:PHP 使用单线程处理方法,在线程完成处理之前不会发回 ACK 文件。有没有办法让它成为一个多线程进程?线程 #1 - 接受传入的 SOAP 请求并发送回 ACK 线程 #2 - 处理 SOAP 请求

我知道我可以把它分解成一个数据库表或平面文件,但是有没有办法在不这样做的情况下做到这一点?

我将在 ACK 提交后尝试关闭套接字并继续处理,交叉手指它会起作用。

4

5 回答 5

1

听起来出站消息正在超时。其他用户报告的超时时间低至 10 秒(请参阅下面的论坛链接)。我使用的沙箱实例 (cs1) 在我的测试中大约 1 分钟后超时。超时可能是 Salesforce 控制的组织或实例级别设置。

您可以尝试两件事:

  1. 使用 Salesforce 打开支持票证,查看他们是否可以增加出站消息的超时值。根据我的经验,他们可以在组织级别修改很多设置——这可能就是其中之一。

  2. 卸载您的数据处理,以便将 ACK 立即发送回 Salesforce。然后,您的数据的实际处理将异步进行。IE。消息队列、单独线程等

其他一些可能有用的资源:

相关 Salesforce 论坛讨论

出站消息传递文档

于 2010-03-22T21:22:42.190 回答
1

我认为他们将等待您的脚本结束的事情超时。

有一种方法可以尝试解决此问题。

在开始时输出带有 ack 消息的信封,然后刷新该内容,以便他们的服务器在您结束处理之前获取它。没有线程,只是重新考虑简单的优先事项:)

阅读此内容以获得有关刷新内容的最佳信息

于 2010-03-26T10:26:38.167 回答
0

您是否 100% 确定 Salesforce 会等待您的脚本运行所需的时间?80秒对我来说似乎很长。

如果所有请求都失败,我猜 Salesforce 希望您Content-Type适当地设置标头,但情况似乎并非如此。

于 2010-03-18T19:32:58.800 回答
0

我不了解 Salesforce,但是如果您想使用 PHP 进行一些多线程处理,您应该看看这个代码示例,更准确地说是pcntl_fork()

注意: pcntl默认情况下启用,并且无法在 Windows 平台上运行。

于 2010-03-29T11:30:03.057 回答
0

所以我所做的是:

  1. 接受所有传入的 OBM,将它们解析为数据库
  2. 完成后启动在后台运行的进程(实际上我将其发送到后台以便脚本可以结束)
  3. 发回 ACK 文件

通过只接受原始数据,解析成字段并将其插入数据库是相当快的。然后我发出一个 Linux 命令行命令,该命令还发送处理脚本以在后台运行。然后我将 ACK 文件发送到 SF,脚本在分配的时间内结束。将脚本过程分成两个单独的阶段很麻烦,但它可以工作。

于 2010-09-10T18:31:55.537 回答