Trước tiên, tôi đề nghị bạn hãy xem http://www.amazon.com/Interfaces-Implementations-Techniques-Creating-Reusable/dp/0201498413. Hầu hết các trình duyệt thứ hai là không đồng bộ, do đó bạn sẽ cần thư viện sự kiện như libuv
hoặc libev
. Ngoài ra, hầu hết các trang web hiện đại đều yêu cầu javascript hoạt động bình thường, nhưng việc thêm một công cụ javascript vào trình duyệt của bạn sẽ làm phức tạp nhiều dự án. Tôi cũng không thấy bất kỳ đề cập nào về cách bạn lập kế hoạch phân tích cú pháp http được gửi đến và từ trình duyệt của bạn, tôi đề xuất https://github.com/joyent/http-parser.
Đối với câu hỏi của bạn về luồng điều khiển, tôi sẽ có chức năng phân tích phản hồi từ máy chủ và sử dụng switch()
để xử lý các loại dữ liệu khác nhau được gửi tới trình duyệt của bạn. Có một trường trong tiêu đề http giải thích loại nội dung và theo cách đó, trình duyệt của bạn sẽ có thể gọi các chức năng khác nhau dựa trên loại nội dung.
Ngoài ra hãy xem các con trỏ hàm, cả ở đây Polymorphism (in C) và tại đây How do function pointers in C work?. Con trỏ chức năng sẽ/có thể là một cách hùng hồn hơn để giải quyết vấn đề của bạn thay vì có các câu lệnh chuyển đổi lớn thông qua mã của bạn. Với các con trỏ hàm, bạn có thể có một hàm mà khi được gọi trong chương trình của bạn hoạt động khác nhau.
Tôi sẽ cố gắng giải thích bên dưới bằng trình duyệt làm ví dụ.
Vì vậy, giả sử trình duyệt của bạn vừa nhận được phản hồi http từ một số máy chủ. Câu trả lời http trông giống như thế này trong C
.
struct http_res
{
struct http_header *header;
struct http_body *body
int (*decode_body)(char **);
};
Vì vậy, trình phân tích cú pháp http đầu tiên sẽ phân tích tiêu đề http và tìm hiểu xem đó có phải là phản hồi hợp lệ và nếu có nội dung, v.v.Nếu có nội dung, trình phân tích cú pháp sẽ kiểm tra loại và dựa trên, nếu đó là html, javascript, css hoặc bất kỳ trình phân tích cú pháp nào sẽ đặt con trỏ hàm trỏ tới hàm đúng để giải mã cơ thể http.
static int decode_javascript(char **body)
{
/* Whatever it takes to parse javascript from http. */
return 0;
}
static int decode_html(char **body)
{
/* Whatever it takes to parse html from http. */
return 0;
}
static int decode_css(char **body)
{
/* Whatever it takes to parse css from http. */
return 0;
}
int parse_http_header(struct http_res *http)
{
/* ... lots of other code to figure out content type. ... */
switch(body_content_type)
{
case BCT_JAVASCRIPT:
http->decode_body = &decode_javascript;
break;
case BCT_HTML:
http->decode_body = &decode_html;
break;
case BCT_CSS:
http->decode_body = &decode_css;
break;
default:
printf("Error can't parse body type.\n");
return -1;
}
return 0;
}
Bây giờ khi chúng ta vượt qua những yêu cầu http đến một phần khác của trình duyệt có chức năng có thể gọi decode_body()
trong đối tượng phản ứng http và nó sẽ kết thúc với một cơ thể được giải mã nó có thể hiểu, với ra biết những gì nó giải mã.
int next_function(struct http_res * res)
{
char *decoded_body;
int rtrn;
/* Now we can decode the http body with out knowing anything about
it. We just call decode_body() and end up with a buffer with the
decoded data in it. */
rtrn = res->decode_body(&decoded_body);
if(rtrn < 0)
{
printf("Can't decode body.\n");
return -1;
}
return 0;
}
Để làm cho chương trình của bạn thực sự mô-đun ít nhất là trong C
, bạn sẽ dính vào các phần khác nhau của trình duyệt của bạn trong các thư viện chia sẻ khác nhau, như phân tích cú pháp HTTP, thư viện sự kiện, động cơ Javascript, html phân tích cú pháp, vv, vv Sau đó, bạn sẽ tạo ra các giao diện giữa mỗi thư viện và bạn có thể trao đổi từng thư viện với một thư viện khác với việc phải thay đổi chương trình của bạn, bạn sẽ liên kết một thư viện khác vào thời gian chạy. Hãy xem Tiến sĩ Robert martin (chú bob) ông nói về điều này rộng rãi. Cuộc nói chuyện này là tốt nhưng nó thiếu slide https://www.youtube.com/watch?v=asLUTiJJqdE, bắt đầu lúc 8:20. Điều này cũng thú vị, và nó có slide: https://www.youtube.com/watch?v=WpkDN78P884.
Và cuối cùng không có gì về C
, perl
hoặc python
có nghĩa là bạn sẽ phải mã hóa logic chương trình của mình. Bạn sẽ phải thiết kế chương trình của bạn để mỗi mô-đun không biết về nhau. Module này biết về giao diện và nếu bạn kết nối hai mô-đun mà cả hai "nói" cùng một giao diện, bạn sẽ tạo ra một hệ thống mô-đun. Nó giống như cách internet hoạt động trên các máy tính khác nhau trên internet không cần biết máy tính khác là gì, hoặc nó đang hoạt động, hoặc hệ điều hành, tất cả những gì họ cần biết là TCP/IP
và họ có thể liên lạc với tất cả các thiết bị khác trên mạng.
Có thể đáng chú ý là một trình phân tích cú pháp XML (libxml2) * không thể * phân tích cú pháp HTML trực tiếp. Trước tiên, bạn sẽ phải chạy HTML thông qua một bước chuyển đổi nó thành cú pháp XML chính xác, điều này sẽ là một thách thức (và sau đó bạn đã viết một trình phân tích cú pháp HTML). –
Tôi thực sự không hiểu ý bạn là gì. Bạn gửi một yêu cầu và sau đó bạn nhận được một phản hồi, khi bạn làm sau đó bạn kiểm tra xem nó là gì và gọi hàm thích hợp để làm những gì bạn muốn -> (Render HTML, Mở một tệp PDF ... vv), tại sao bạn cần phải ** recode ** toàn bộ điều? Ý tưởng của bạn về điều đó không có ý nghĩa với tôi. –
@GregHewgill AFAIK 'libxml2' có giao diện trình phân tích html. –