当前,我们正在开发域注册器API。
$options = [
'ssl' => [
'verify_peer' => true,
'local_cert' => __DIR__ . '/Domain.pem',
'local_pk' => __DIR__ . '/Domain.pem',
'allow_self_signed' => true,
]
];
$context = stream_context_create($options);
$ch = stream_socket_client($serverPath.':'.$parentClass->port, $errorNumber, $errorString, 60, STREAM_CLIENT_CONNECT, $context);
stream_set_timeout($ch, 60);
fwrite($ch, $command);
$data = '';
while (!feof($ch)) {
$data .= fread($ch, 1024);
}
fclose($ch);
在重写XML请求之后
<epp xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<login>
<clID>User</clID>
<pw>Password</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>urn:ietf:params:xml:ns:obj1</objURI>
<objURI>urn:ietf:params:xml:ns:obj2</objURI>
<objURI>urn:ietf:params:xml:ns:obj3</objURI>
<svcExtension>
<extURI>http://custom/obj1ext-1.0</extURI>
</svcExtension>
</svcs>
</login>
<clTRID>ABC-12345</clTRID>
</command>
</epp>
fread给出问候消息,而不是有关登录请求的状态码。 这种读取响应的方法正确吗?不能从服务器获得正确答案的原因可能是什么?谢谢
答案 0 :(得分:2)
EPP无法像您所想的那样工作。首先,我建议您花一些时间阅读RFC5730和5734的详细信息,下面将对它们进行讨论。完成这项工作后,您将需要全面了解RFC 5731 5732和5733中的所有EPP详细信息。不要指望能够在不阅读所有EPP客户端的情况下编写成功的EPP客户端。
现在回到您的问题,以及为什么不遵循EPP规范。
请参见RFC5730的第2节,此处转载:
|
V
+-----------------+ +-----------------+
| Waiting for | Connected | Prepare |
| Client |----------------->| Greeting |
+-----------------+ or <hello> +-----------------+
^ |
| Close Connection Send |
| or Idle Greeting |
+-----------------+ V
| End | Timeout +-----------------+
| Session |<-----------------| Waiting for |
+-----------------+ | Client |
^ ^ ^ Send +-------->| Authentication |
| | | Response | +-----------------+
| | | +--------------+ |
| | | | Prepare Fail | | <login>
| | +-----| Response | | Received
| | Send +--------------+ V
| | 2501 ^ +-----------------+
| | Response | | Processing |
| | +---------| <login> |
| | Auth Fail +-----------------+
| | Timeout |
| +-------------------------------+ | Auth OK
| | V
| +-----------------+ <hello> +-----------------+
| | Prepare |<----------| Waiting for |
| | Greeting |---------->| Command or |
| +-----------------+ Send | <hello> |
| Send x5xx Greeting +-----------------+
| Response +-----------------+ Send ^ |
+-----------| Prepare | Response | | Command
| Response |----------+ | Received
+-----------------+ V
^ +-----------------+
Command | | Processing |
Processed +----------| Command |
+-----------------+
不同的说法是,客户的行为方式:
程序中的错误是您的客户端先讲话,然后向服务器发送内容。根据上述状态架构,不允许这样做,因此请先阅读服务器回复。
因此,您的问题不是专门发送XML(尽管您也对此有疑问,请参见下文),首先,它不尊重谁先讲话的顺序。
也不要这样做:
while (!feof($ch)) {
$data .= fread($ch, 1024);
}
请参阅说明如何传输EPP的RFC 5734。总而言之,也要回答上面关于您的问题的一些评论:
因此,当您希望收到服务器发出的消息时,您会像这样:
但是请注意,将内容发送到服务器时,您需要执行相同的操作! 不要仅发送XML内容,而是需要形成适当的EPP框架,这意味着:
此外,作为行业中的“老将”(已经存在20年了,既编写了EPP服务器,客户端,也参与了定义它的RFC),请从经验中采纳此建议:如果您的工作是是只连接到一个注册表,那么生活很简单;您甚至可以使用注册表提供的工具箱,只要它是您选择的语言即可。
但是,一旦您需要编写一个能够正确连接到多个注册表的客户端,便会遭受痛苦。即使这是一个标准,您也会在注册表中发现很多变化,涉及许多主题,例如如何报告扩展的错误数据,存在哪些EPP扩展名以及它们如何工作,域响应的内容:检查等,细微差别的列表在这里只列举了很久。
由于上述所有原因,您可能也不想重新发明轮子。 有一些库可以为您完成所有EPP任务,例如https://github.com/centralnic/php-epp 我不以任何方式认可它,因为我不使用PHP,所以我不知道它,但是也许可以帮到您,要么按原样重用,以便您没有编写代码,或者至少看看看看他们是如何解决特定问题的,以便您受到启发。
例如上述有关长度和每个EPP帧开头的4个字节的问题,请参见https://github.com/centralnic/php-epp/blob/master/Net/EPP/Protocol.php中的getFrame
和sendFrame