php与前端界面的实时通信

新手上路,请多包涵

问题描述

我在前端界面调用php代码,该php代码实现的是与python写的爬虫程序建立socket连接,然后开始爬虫。
因为爬虫程序会有输出,而且输出也不是一次性的,每爬虫到一张图片就会有一个输出,我想把这些信息返回到前端界面显示。
对于这样的通信,我用什么样的方式会比较好呢?没有通信这边的基础,看到网上有说ajax、socket、websocket这些,但是看得有点迷糊,请各位请教有什么思路吗?用什么样的方式最适合我现在的这种情况呢?

问题出现的环境背景及自己尝试过哪些方法

我现在暂时用cookies来实现,问题是要刷新页面才会收到返回的结果。

相关代码

这是客户端php代码:

<?php
set_time_limit(0); // 改脚本无上限
$info = "";
// 传入爬虫参数
$keywords = $_POST['keywords'];
$limit = $_POST['limit'];
$size = $_POST['size'];
$image_directory = $_POST['image_directory'];

// $keywords = "人脸皮肤病";
// $limit = 2;
// $size = ">4MP";
// $image_directory = "img/downloads";

// 与服务端端口建立连接
$handle = fsockopen("127.0.0.1", 8001);

if ($handle) {
    // 传递爬虫参数给python服务端
    fputs($handle, $keywords . "#" . $limit . "#" . $size . "#" . $image_directory);
    stream_set_blocking($handle, true); // 重要,设置为非阻塞模式
    
    while (!feof($handle)) {
        $info .= fgets($handle, 128); //从服务端接收爬虫返回信息
        // ob_flush();
        // flush(); // 刷新输出缓冲区,获取数据
    } 
    if($info) {// 判断爬虫是否成功运行
        // 获取当前时间,储存在cookies
        $time =  date("Y-m-d--H:i:s");
        setcookie('crawler_finished_time', $time);
        // 以当前时间创建cookie名,储存爬虫结果信息,传给前端界面
        setcookie($time, $info);
        ob_flush();
        flush(); // 刷新输出缓冲区,获取数据
    }
    else
        echo "爬虫失败"; 
}

fclose($handle);

这是包含爬虫程序的服务端代码:

#!/usr/bin/python
import socket
import subprocess
import crawler
import test

socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

socket.bind(('127.0.0.1',8001))

socket.listen(5)

while True:
    # 与客户端连接
    connection,addr = socket.accept()
    
    buf=connection.recv(1024).decode('utf-8')
    buf = buf.split('#')
    # 将爬虫参数传给爬虫函数,并返回下载图片的详细信息
    info = crawler.start(buf[0], buf[1], buf[2], buf[3])

    connection.send(("" + ",".join(info[0][buf[0]])+ "," + str(info[1]) + "\n").encode('utf-8'))

    connection.close()

你期待的结果是什么?实际看到的错误信息又是什么?

每爬虫到一张图片就会有一个输出,我想把这些信息实时返回到前端界面。中间传输的数据很小,就是一些文本信息。

阅读 4k
3 个回答
  1. 如果你只是启动服务,然后不断看输出,最佳方案是 SSE
  2. 如果你还要发一些命令过去,可以考虑用 WebSocket
  3. 最简单的做法,用 ajax,每隔一分钟请求一次,把上次的最后位置传过去,从服务器端获取片段
新手上路,请多包涵

感谢各位的回答,最后我使用的是js的reconnecting-websocket库(websocket)作客户端,该库可以自动重连;然后用python的pywss库(websocket)作服务端,该库使用简单,最终实现前后端双工通信。

推荐问题
宣传栏