上周四發表了一篇日志《一定要寫的日志》,里面寫了我遇到問題與解決問題痛苦經歷,但具體遇到的問題沒有細說。因為項目一直很忙,分身乏術,直到今天中午我終於完成了項目,解決了所有的技術問題,現在才有時間具體說一下所遇到的問題。但是既然寫了,就把這兩周遇到的所有難題和解決問題的經歷和感受都說一下。
先說一下項目背景。
我們公司做了一套網上在線學習平台,是用c# .net開發的,用iis7部署在windows平台上,但是,領導層感覺這種方式代價太大,所以決定改用php開發,部署采用一鍵安裝式部署,但是我們公司沒有一個人用過php,我們都是用c# .net 開發。
經過領導們商議,將任務交給了本人,項目時間截止點是10月底。我是上月(也就是9月份)23號接到的任務,接到任務后,大概用了三四天的時間將手頭工作交接,在27,28號的時候,全身心研究php。
很快就放假了,我本來想在放假期間好好研究php的,但是,但是你們知道的,放假在家根本沒有心思研究技術,痛痛快快的玩了7天。
放假回來了,前三天還是沒有上手寫程序,搭建開發環境,了解開發框架用了大概用了三四天,又用兩天時間用php寫了一個單表的增刪改,分頁,這才開始真正進行我的項目。
真正的做項目,簡單的部分完成后,很快就遇到難題了。我大致把問題划分為以下幾個。
①服務轉換,服務轉換的作用是為了把用戶上傳的文件,可以用flash直接播放,用的技術主要是rabbitmq,服務轉換程序我們的.net版本已經做好了,並且很成熟。我要做的就是部分更改.net程序,然后用php程序向.net服務發請求,具體過程是將請求放入到rabbitmq隊列中,然后由rabbitmq和.net進行通信。
②轉換后的資源的預覽問題,資源轉換后有jpg、png、doc、docx、ppt、pptx、pdf、txt....類型,這些類型都需要預覽。我們有.net版本的預覽程序,我要做的就是要把.Net
程序翻譯為php程序。
③在線學習flash接口實現。
在線學習flash接口實現主要是和flash端人員進行協同開發,整個過程還算順利。
服務轉換遇到了種種難題。
首先是安裝rabbitmq,安裝rabbitmq非常順利,一百度一大把。
第二步利用rabbitmq向.net轉換服務發送請求。
進入官方網站查看文檔,以上是導航頁。這么多種請求方式,看了下,第一種就是我所需要的,果斷點進去查看。
重要內容如下:
1.介紹wamp原理以及重要術語Producing,queue,Consuming
英文介紹這么多,實際上就是 生產者-隊列-消費者原理,在這里,我知道,我的php程序發送請求是生產者,發送的內容是消息隊列,.net服務處理程序是消費者。
2.發送一個消息的具體過程
這段文字是敘述如何在寫發送實例之前,必須要安裝composer和amqplib。
下面一段php代碼是發送實例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php
require_once
__DIR__ .
'/vendor/autoload.php'
;
use
PhpAmqpLib\Connection\AMQPConnection;
use
PhpAmqpLib\Message\AMQPMessage;
$connection
=
new
AMQPConnection(
'localhost'
, 5672,
'guest'
,
'guest'
);
$channel
=
$connection
->channel();
$channel
->queue_declare(
'hello'
, false, false, false, false);
$msg
=
new
AMQPMessage(
'Hello World!'
);
$channel
->basic_publish(
$msg
,
''
,
'hello'
);
echo
" [x] Sent 'Hello World!'\n"
;
$channel
->close();
$connection
->close();
?>
|
問題就出現了安裝composer和amqplib上。官方文檔一點不詳細,並且直接運行官方文檔的 $ composer.phar install 語句還會報錯。
安裝這兩個東西的注意事項我寫下:
composer安裝過程
①到https://getcomposer.org/ 網站下載composer安裝包
②把php.ini文件中;extension=php_openssl.dll的分號去掉
③安裝文件。
如果上述第②步沒有做的話,必然報錯。
ampqlib安裝過程
①到https://github.com/videlalvaro/php-amqplib/archive/master.zip 下載amqplib壓縮包
②將壓縮包解壓到網站根目錄,注意是根目錄
③創建composer.json文件到根目錄內容為:
{
"require": {
"videlalvaro/php-amqplib": "2.2.*"
}
}
④在cmd下,將目錄指向項目根目錄(用cd命令),執行 php composer.phar
執行成功后會有如下提示:
- Installing videlalvaro/php-amqplib (v2.2.6)
Downloading: 100%
向.net程序發指令
一直失敗,最后反編譯.Net發送代碼,寫出如下php代碼才成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$exchange
=
'router'
;
$queue
=
'push_queue'
;
$conn
=
new
AMQPConnection(
'localhost'
, 5672,
'guest'
,
'guest'
,
'/'
);
$ch
=
$conn
->channel();
$ch
->queue_declare(
$queue
, false, true, false, false);
$ch
->exchange_declare(
$exchange
,
'direct'
, false, true, false);
$ch
->queue_bind(
$queue
,
$exchange
);
$msg_body
= implode(
' '
,
array_slice
(
$argv
, 1));
$arr
=
array
(
'Type'
=>
'Convert'
,
'ID'
=>
$docid
);
$msg
=
new
AMQPMessage(json_encode(
$arr
),
array
(
'content_type'
=>
'text/plain'
,
'delivery_mode'
=> 2) );
$ch
->basic_publish(
$msg
,
$exchange
);
$ch
->close();
$conn
->close();
echo
'success'
;
|
經過多次調試,轉換服務終於順利運行。
資源預覽問題。
經過調試,png,txt,jpg,MP3,MP4等文件格式都已經可以預覽,但是office文件和pdf文件不能預覽。.預覽office和pdf的c#代碼是一致的,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
context.Response.ContentType =
"application/x-shockwave-flash"
;
dir = Path.Combine(dir,
"swf"
);
int
pn = StringUtil.ToInt(context.Request.QueryString[
"pn"
], 1);
int
rn = StringUtil.ToInt(context.Request.QueryString[
"rn"
]);
int
totalPage = doc.ThumbCount;
if
(pn < 1 || rn < 1 || totalPage == 0)
{
dir = Path.Combine(dir, version_str +
".swf"
);
}
else
{
using
(MemoryStream ms =
new
MemoryStream())
{
byte
[] bytes = Encoding.UTF8.GetBytes(
"{\"totalPage\":\""
+ totalPage +
"\",\"fromPage\":\""
+ pn +
"\",\"toPage\":\""
+ (pn + rn) +
"\"}\r\n"
);
ms.Write(bytes, 0, bytes.Length);
for
(
int
i = pn; i < pn + rn; i++)
{
string
filename = Path.Combine(dir, version_str +
string
.Format(
".{0}.swf"
, i));
if
(!File.Exists(filename))
break
;
bytes = File.ReadAllBytes(filename);
ms.Write(bytes, 0, bytes.Length);
}
context.Response.BinaryWrite(ms.ToArray());
}
return
;
}
|
c#原理很簡單,用json字符串記錄 文件的分頁信息,轉化為字節數組並放入流中,然后循環文件並讀取放入流中,最后輸出流的字節數組形式。
我的第一反應是:php肯定也有流的定義,於是研究php的api,發現的確有streams文檔,但是我沒有找到相應.net方法。文檔研究了整整一天,的確沒有解決方案(哪位php大神有解決方案請告之)。
第二種思路改為將json字符串讀為字節數組,將文件也讀為字節數組,然后合並字節數組,最后輸出字節數組。
我對這個解決方案深信不疑。認為肯定可以。但是當我發現.net輸出的字節數組內容和php輸出的字節數組內容不一樣時,頓時心灰意冷。又苦苦掙扎了近一個小時才放棄這種思路。
第三種思路,就是用php的header直接以二進制輸出,這種思路是可行的,走通了,相應php代碼如下:
$pn=$this->input->get("pn"); $rn= $this->input->get("rn"); $totalPage=$file_count; $json="{\"totalPage\":\"" . $totalPage . "\",\"fromPage\":\"" . $pn ."\",\"toPage\":\"" . ($pn + $rn) ."\"}\r\n"; header('Content-Type: application/x-shockwave-flash'); header("Content-Transfer-Encoding: binary"); echo $json;for ($i = $pn; $i < $pn + $rn; $i++) { $filename=ROOTPATH.$Dir.'/swf/'.$version.'.'.$i.'.swf'; $handle=fopen($filename,"r");//使用打開模式為r $content=fread($handle,filesize($filename));//讀為二進制 //$filearr=file($filename); echo $content; } exit;
展示一下預覽office文件效果:
“當你為一個問題愁眉不解,苦苦思索,痛苦萬分的時候,這個問題已經不是問題了,因為,你遲早會解決他!”
遇到難題,只要我們不投降,總有解決方案,因為,在技術上,沒有解決不了的難題。