【问题标题】:use existing PHP socket使用现有的 PHP 套接字
【发布时间】:2018-01-21 18:03:10
【问题描述】:

这是我第一次在论坛发帖,对于新手的任何错误,我们深表歉意......

我有一个 php 脚本,它打开一个到服务器的流式套接字,发送一个请求并等待响应消息。脚本如下所示:


<?php
$addr="192.168.1.1";
$port=6010;

$sock = fsockopen("tcp://$addr:$port", $errno, $errstr, $timeout) or die("socket problem");
stream_set_timeout($sock,30) or die("timeout not set");

$message='<?xml version="1.0" encoding="UTF-8"?><Request><Type>1</Type></Request>'

$slen=pack("N",strlen($message));

fwrite($sock,$slen.$message);

ob_flush();flush();

while((!feof($sock)) && (!$info['timed_out'])){
    $b3=fread($sock,3);
    $b4=fread($sock,1);
    $temp=unpack("N",$b3.$b4);
    $length=$temp[1];
    $lines=fread($sock,$length);
    if($lines){
        if(preg_match("'<Response>(.*?)</Response>'",$lines, $match)){
            if($match){
                $content=$match[1];
                echo nl2br($content);
            }
        }
    }
    $info = stream_get_meta_data($sock);
}
fclose($sock);
?>

上面的脚本运行良好,但我想添加功能(取消按钮)以退出 while 循环并使用相同的套接字向服务器发送取消消息,例如类型 0

问题是提交会刷新页面并释放当前的 $sock。

任何想法或简单的解决方案都将受到高度赞赏。

谢谢。 T.

【问题讨论】:

  • 我能想到的就是你正在执行的脚本需要检查一些外部的东西,比如从数据库、磁盘上的文件中读取状态,或者让会话处理程序开始和停止每个迭代以知道何时更改处理。

标签: php sockets stream


【解决方案1】:

详细说明@Scuzzy 的建议,一种选择是让“取消按钮”异步调用另一个php 脚本。这将在文件/磁盘/数据库(您的选择)上设置一个标志,指示用户要求取消。

异步调用将保留主 php 脚本上的会话。

在这里的主循环中,您会定期检查该标志的状态,如果设置了标志,则立即退出,如果需要,执行额外的清理。

主循环的伪代码是:

<?php
/*
   All the initialization
*/

cancelOperation = False;
while((!feof($sock)) && (!$info['timed_out'])){
    $b3=fread($sock,3);
    $b4=fread($sock,1);
    $temp=unpack("N",$b3.$b4);
    $length=$temp[1];
    $lines=fread($sock,$length);
    if($lines){
        if(preg_match("'<Response>(.*?)</Response>'",$lines, $match)){
            if($match){
                $content=$match[1];
                echo nl2br($content);
            }
        }
    }
    $info = stream_get_meta_data($sock);

    // Now check external condition, from either file or db for example
    cancelOperation = checkExternalCondition();
    if (cancelOperation === True) {
        break;
    }
}
if (cancelOperation === True) {
    // additional cleanup needed goes here.
}
fclose($sock);
?>

【讨论】:

  • 感谢 Scuzzy 和 Sal 的意见。我将测试建议的方法,以找出最合适的方法......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 2017-09-14
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多