2012-05-03 13 views
9

Tôi đang làm việc trên một dự án có liên quan đến một số chương trình C++ mà mỗi chương trình lấy đầu vào và tạo đầu ra. Dữ liệu (hàng chục đến hàng trăm byte, có thể là JSON) về cơ bản chảy (không đồng bộ) theo một hướng, và các chương trình sẽ cần phải được đặt trên các máy tính Linux khác nhau xung quanh mạng LAN.Đề xuất cho hàng đợi tin nhắn từ xa C/C++

Vì dữ liệu chỉ truyền theo một hướng, tôi không tin rằng tôi cần một mô hình giao dịch như HTTP. Tôi nghĩ rằng một mô hình hàng đợi tin nhắn (lửa và quên) làm cho ý nghĩa nhất và nên đơn giản hóa logic của mỗi chương trình. Nó có lẽ là đủ để chỉ lưu ý rằng thông báo đã được thêm vào hàng đợi từ xa thành công.

Điều tôi đang tìm kiếm là các đề xuất về cách triển khai hàng đợi thư này trong C hoặc C++. Có vẻ như POSIXBoost hàng đợi thư bị giới hạn ở một máy chủ duy nhất và RabbitMQ dường như có hỗ trợ C/C++ yếu và MQ4CPP dường như không được hỗ trợ đầy đủ cho vai trò quan trọng trong kinh doanh. Tôi có sai về điều này không? Điều gì về Boost ASIO hoặc ACE hoặc tự viết mã ổ cắm? Tôi mong các đề xuất của bạn.

+2

[ZeroMQ khá đẹp] (http://www.zeromq.org). – user7116

+0

Câu trả lời hay, mọi người, nhưng tôi thực sự thích sự đơn giản của ZeroMQ. Nếu @sixlettervariables là để làm cho nó một câu trả lời, tôi sẽ chấp nhận nó. –

Trả lời

8

Xét về hỗ trợ nhắn tin đơn giản, ZeroMQ is hard to beat. Nó có sẵn trong nhiều ràng buộc ngôn ngữ và hỗ trợ tất cả mọi thứ từ gửi đơn giản và nhận được đến pub/sub, fanout, hoặc thậm chí là một đường dẫn tin nhắn. Mã này cũng dễ tiêu hóa và làm cho nó dễ dàng chuyển đổi giữa các mẫu.

Nhìn vào Weather Update Server sample (trong 20 số ngôn ngữ lẻ) của họ cho thấy cách dễ dàng có thể để tạo ra xuất bản/đăng ký thiết lập:

zmq::context_t context (1); 
zmq::socket_t publisher (context, ZMQ_PUB); 
publisher.bind("tcp://*:5556"); 
publisher.bind("ipc://weather.ipc"); 

while(1) { 
    // Send message to all subscribers 
    zmq::message_t message(20); 
    snprintf ((char *) message.data(), 20 , 
     "%05d %d %d", zipcode, temperature, relhumidity); 
    publisher.send(message); 
} 

Tôi đã sử dụng nó trên một số C hỗn hợp các quy trình Python # và không gặp rắc rối nhiều .

1

Tôi đang sử dụng Tăng tốc nối tiếp và gửi ổ cắm cho một ứng dụng tương tự. Bạn có thể tìm thấy một ví dụ về serialization đây:

http://code.google.com/p/cloudobserver/wiki/TutoriaslBoostSerialization

Và trên trang này:

http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

dưới serialization bạn sẽ tìm thấy những ví dụ về cách làm cho máy chủ và khách hàng. Tạo một máy chủ trên một cổng cụ thể và bạn có thể tạo nhiều máy khách trên nhiều máy tính có thể giao tiếp với cổng đó.

Nhược điểm của việc sử dụng đẩy mạnh tuần tự hóa là nó có một chi phí lớn nếu bạn có một cấu trúc dữ liệu đơn giản được tuần tự hóa nhưng nó làm cho nó dễ dàng.

2

Cá nhân, nếu tôi hiểu câu hỏi, tôi nghĩ rằng bạn nên sử dụng kết nối TCP cấp thấp hơn. Nó có tất cả các giao hàng bảo lãnh mà bạn muốn, và có một API socket Berkley khá tốt. Tôi thấy rằng nếu bạn sẵn sàng triển khai một giao thức rất đơn giản (ví dụ: chiều dài tin nhắn NBO bốn byte, n byte dữ liệu), bạn có thể rất đơn giản, rất tùy chỉnh và rất đơn giản. Nếu bạn đi với điều này, bạn cũng (như đã đề cập) được hỗ trợ C tuyệt vời (có nghĩa là hỗ trợ C++, mặc dù mọi thứ không có trong các lớp và phương thức). Mã socket cũng rất dễ dàng, và chúng có IO không đồng bộ với các cờ async chuẩn cho các hàm IO của Linux/UNIX/POSIX (đó là một trong những lợi ích khác, nếu bạn biết gì về lập trình POSIX, về cơ bản bạn biết API socket) .

Một trong những nguồn lực tốt nhất cho việc học tập các API ổ cắm là:

  • Beej của Hướng dẫn Mạng Lập trình: http://beej.us/guide/bgnet/, điều này rất tốt nếu bạn cần mô hình lập trình tổng thể, thêm vào chi tiết cụ thể
  • Man Trang : Nếu bạn chỉ cần chữ ký chức năng, giá trị trả về và đối số, đây là tất cả những gì bạn cần. Tôi tìm thấy Linux được viết rất tốt và hữu ích (Bằng chứng: Nhìn vào bảng điều khiển của tôi: man, man, man, man, man, make, man, ...)

Ngoài ra, để làm cho mạng dữ liệu có thể gửi được, nếu dữ liệu của bạn là JSON, bạn không phải lo lắng. Bởi vì JSON chỉ là ASCII (hoặc UTF-8), nó có thể được gửi thô qua mạng chỉ với một tiêu đề chiều dài. Trừ khi bạn cố gắng gửi một cái gì đó phức tạp trong nhị phân, điều này nên được hoàn hảo (nếu bạn cần phức tạp trong nhị phân, hoặc xem serialization hoặc chuẩn bị cho rất nhiều Segmentation Fault).


Ngoài ra, bạn có thể, nếu bạn đi đường dẫn ổ cắm, muốn sử dụng TCP. Mặc dù UDP sẽ cung cấp cho bạn khía cạnh một chiều, thực tế là làm cho nó đáng tin cậy là pitting giải pháp nhà của bạn so với TCP đầu tiên của hạt nhân Linux, TCP là một lựa chọn hiển nhiên.

1

Một đề xuất khác là khung phân phối OpenCL. Tài liệu The OpenCL C++ Wrapper for API cung cấp thêm thông tin về thư viện. Cụ thể, chức năng API cl::CommandQueue có thể được quan tâm để tạo hàng đợi trên các thiết bị trong một thiết lập mạng.

2

RabbitMQ chỉ là một triển khai thực hiện AMQP. Bạn có thể muốn điều tra Apache Qpid hoặc các biến thể khác có thể thân thiện với C/C++ hơn. Có một libamqp cho C mặc dù tôi không có kinh nghiệm tay đầu tiên với nó. Tôi không biết chính xác yêu cầu của bạn là gì nhưng AMQP, được triển khai đúng cách, là sức mạnh công nghiệp và nên đơn đặt hàng của cường độ nhanh hơn và ổn định hơn bất kỳ thứ gì bạn sẽ xây dựng bằng tay trong một khoảng thời gian ngắn.

1

Một giải pháp nhắn tin khác là ICE (http://www.zeroc.com/). Nó là đa nền tảng, đa ngôn ngữ. Nó sử dụng nhiều hơn một cách tiếp cận RPC.

+0

Mặc dù đây là một sản phẩm tuyệt vời, [ICE là GPLed] (http://www.zeroc.com/licensing.html). Trừ khi mã của bạn được GPL là tốt hoặc sẵn sàng trả tiền cho một giấy phép thương mại, tôi muốn tránh xa nó. – Void