我们有一个Java的应用服务器和一个PHP的web客户端。
我们希望以一种用户友好的方式将文件从Java服务器传输到客户端。
是否可以使用从Java服务器发送的流在浏览器中触发文件下载?
通信通过套接字,如果有帮助的话。
下面是我在客户端使用Zend Framework所做的尝试。
视图:
<?php
$file = $this->filename;
$filesize = $this->filesize;
header("Content-type: application/octet-stream'r'n");
header('Content-Disposition: attachment; filename="'.$file.'"'r'n');
header("Content-Length:$filesize'r'n");
header("Accept-Ranges: bytes'r'n");
header("Cache-Control: private'n'n");
header("Content-Transfer-Encoding: binary");
header("Connection: Keep-Alive'r'n");
ob_clean();
flush();
$authNamespace = new Zend_Session_Namespace('Cubbyhole_SockLoader');
$cl = $authNamespace->CoreLinker;
$cl->downloadFile($this->fileId, "echo", $this->filesize);
?>
cl -> downloadFile ($ this ->文件标识,"回声",$ this ->文件大小),
读取数据流并回显接收到的内容,直到输出文件长度,然后停止。
问题是,正如预期的那样,在触发下载之前,必须回显整个文件,从而导致PHP端超时,或者只是一个非常长的加载页面。然后,当文件在客户端回显时,客户端必须自己下载文件,这并没有真正优化。
是否有一种方法可以使用PHP异步发送数据到用户的浏览器,并从套接字输出数据流?
也许你应该看看:
http://framework.zend.com/manual/1.12/en/zend.http.client.advanced.html zend.http.client.streaming
和
可以通过Zend HTTP客户端下载文件吗?
还可以看看php中的流和各种I/O流包装器 php://stdin , php://stdout 和 php://stderr :http://www.php.net/manual/de/wrappers.php.php
您当前正在处理一个文件名,它表示驱动器上存储的文件。
你需要做的是,从你的php web客户端请求文件。
所以你的Java服务器应该响应你的web客户端,发送一个文件作为响应。
你的Zend Controller Action应该使用一些客户端来与你的Java Server交互。
如果你的Java服务器正在监听HTTP请求,使用Zend_Http_Client之类的东西来获取响应。
Browser -> Webclient -> Java Server
web客户端和Java服务器都需要能够流式传输数据。
你要做的是,如果一个浏览器从你的Webclient请求一个URI,被调用的Controller Action将从Java Server请求文件作为一个流。
web客户端将获得php流并代理(转发)文件-逐位。
有几种技巧可以使用,所以问一个更详细的问题,如果可以的话,我会试着回答。
玩得开心!
答案很简单。
我需要明确地说输出缓冲在发送报头后结束,以便浏览器将流作为下载源。
<?php
$file = $this->filename;
$filesize = $this->filesize;
header("Content-type: application/octet-stream'r'n");
header('Content-Disposition: attachment; filename="'.$file.'"'r'n');
header("Content-Length:$filesize'r'n");
header("Accept-Ranges: bytes'r'n");
header("Cache-Control: private'n'n");
header("Content-Transfer-Encoding: binary");
header("Connection: Keep-Alive'r'n");
ob_clean();
flush();
ob_end_flush();//here
$authNamespace = new Zend_Session_Namespace('Cubbyhole_SockLoader');
$cl = $authNamespace->CoreLinker;
$cl->downloadFile($this->fileId, "echo", $this->filesize);
?>