Yar:yet another rpc,這是它的全稱。
關於一些基本介紹 http://www.laruence.com/2012/09/15/2779.html 可以去 鳥哥的博客去了解下。
我也簡單介紹下用法,下面的代碼來自鳥哥的博客。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
實例化 Yar_server的時候,需要傳遞一個對象,然後會將我們提交的參數作爲 這個對象的method來使用,其實這個做法就相當於是一個
簡單的路由功能,它巧妙將 doc作爲api的接口說明來使用,讓我們get直接訪問server.php的時候,看到的會是下面的頁面:
整體來講,yar分爲兩部分:server和client.
Server端:
上面有講到server可以理解爲一個簡單的路由,它只是將我們的對象作爲一種服務接口來使用,
它的主要流程如下:
實例化Yar_Server時,傳遞一個自定義API對象,將這個對象保留在 屬性 _executor中,調用handle方法,
如果不是post請求,則只輸出接口說明;
如果是post請求,接收api函數,讀取post數據,檢測 API對象中是否存在此方法,
如果存在就call_user_function_ex來執行此方法,如果不存在bailout。
看下代碼
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
|
關鍵部分已經加了註釋,代碼寫的也通俗易懂。
那現在看Client了:
我之前做的其實就相當於這個client,沒有server端,只是用libcurl+epoll的事件模式去curl我們的接口,有數據返回時,執行
callback函數,看了yar代碼之後,發現 ,思路其實很相似。
使用方法 :
1 2 3 4 5 6 7 8 9 10 11 |
|
Yar_Concurrent_Client::call方法接收四個參數,
第一個是訪問的接口地址,
第二個是需要執行的方法,
第三個是傳遞的參數,
第四個就是回調函數。
還有第五個參數,一個數組,它用來設置options,默認爲空。
這些所有信息保存在 _callstack屬性中。
由Yar_Concurrent_Client::loop()統一發送 接收epoll事件,當發現有一個讀事件時,讀到所有數據然後調用callback。
在擴展實現中有一個數據結構:
1 2 3 4 5 6 7 8 9 10 11 |
|
他保存所有call設置的參數,在執行loop時,會從這裏拿這些信息,
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
client關鍵的地方在php_yar_concurrent_client_handle函數中:
在這之前,有幾個比較重要的數據結構:
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 35 36 |
|
上面的函數指針代碼量比較大,我就不貼代碼了。
下面看 php_yar_concurrent_client_handle喊。
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
|
在執行multi->exec 時,如果所有數據已經讀取成功,就會調用 php_yar_concurrent_client_callback函數,它也是執行 call_user_function_ex的地方,這樣我們設置的callback函數也就執行成功了。
Client 看代碼的過程比較繞,原因就是上面的幾個結構,
yar_transport_t;
yar_transport_multi_t;
yar_transport_multi_interface_t;
yar_transport_interface_t;
關鍵的是yar_transport_multi_t和yar_transport_interface_t,
我們要並行幾個接口,創建幾個 yar_transport_interface_t結構,它保存了curl_easy句柄,
yar_transport_interface_t 創建完成後,調用 yar_transport_multi_t->php_yar_curl_multi_add_handle函數,將
yar_transport_interface_t 指針添加到yar_curl_multi_data_t->chs中,所有的curl句柄添加完後執行
yar_transport_multi_t->php_yar_curl_multi_exec,執行epoll事件模型,所有數據讀取結束後 調用
yar_concurrent_client_callback執行我們傳遞的callback函數,就是這樣。