2013-01-22 23 views
11

Tôi đang xây dựng một hệ thống nhỏ chứa nhiều phần và tôi muốn sử dụng dịch vụ pub/sub message để giao tiếp giữa các phần.Cần một dịch vụ/thư viện pubsub nhẹ

Tôi đã đọc về một số dịch vụ xếp hàng tin nhắn như RabbitMQ và ZeroMQ nhưng tôi cảm thấy chúng quá phức tạp và cảm thấy như được sinh ra cho hệ thống phân phối. Tất cả các phần của hệ thống của tôi sẽ được viết bằng C++/Linux và đặt trên một CPU Raspberry Pi nhỏ, vì vậy tôi không cần tính năng như có thể mở rộng, đa nền tảng, các ứng dụng ngôn ngữ khác ...

Các bạn có thể cho tôi một số lời khuyên không về các dịch vụ hoặc thư viện phù hợp với nhu cầu của tôi? Hoặc bạn

Cảm ơn.

+0

Bạn có cần sử dụng lib hoặc dịch vụ không? Hoặc bạn có thể, đưa ra các điều kiện tiên quyết, chỉ cần sử dụng ổ cắm hoặc đường ống? Đó sẽ là, có khả năng, hiệu quả hơn cho một quả mâm xôi. –

+1

ZeroMQ rất đơn giản để sử dụng. – Kimi

+1

@ dema80: Tôi thích dịch vụ hơn nhưng lib thì ổn. Bạn có thể đề nghị bất kỳ thực hiện sử dụng ổ cắm? – Yoshi

Trả lời

7

Không khó để tự mình thực hiện.

Trước hết, bạn cần xác định giao thức sẽ được sử dụng. Nó có thể rất đơn giản; giống như trường loại tin nhắn, trường tải trọng và trọng tải thực tế. Các loại tin nhắn bạn cần SUBSCRIBE, UNSUBSCRIBEPUBLISH. Tải trọng cho các thông báo SUBSCRIBEUNSUBSCRIBE là tên của kênh đăng ký/hủy đăng ký. Trọng tải cho thông báo PUBLISH là tên kênh và dữ liệu thực tế (cùng với kích thước của dữ liệu của khóa học).

Để kết nối tất cả người đăng ký, bạn cần một máy chủ trung tâm. Tất cả người đăng ký/nhà xuất bản cần kết nối với máy chủ này. Chương trình máy chủ giữ một tập hợp các hàng đợi, một cho mỗi kênh. Khi thông báo đăng ký hoặc xuất bản đến máy chủ cho kênh không tồn tại, hãy tạo hàng đợi tin nhắn mới cho kênh này. Đối với mỗi kênh, máy chủ cũng cần một bộ sưu tập của tất cả các khách hàng đăng ký kênh đó. Khi thông báo xuất bản đến máy chủ, nó sẽ được thêm vào cuối hàng đợi cho kênh được đề cập. Mặc dù hàng đợi kênh không trống, gửi bản sao của nó cho tất cả người đăng ký kênh đó và khi tất cả đã nhận được thì thư có thể bị xóa khỏi hàng đợi.

Phần cứng của máy chủ có thể sẽ là phần giao tiếp. Phần dễ dàng sẽ được tất cả hàng đợi và bộ sưu tập, như bạn có thể sử dụng C++ standard containers cho tất cả trong số họ (ví dụ std::queue cho hàng đợi thực tế, std::unordered_map cho các kênh, và std::vector cho bộ sưu tập của khách hàng được kết nối.)

Các khách hàng rất đơn giản, tất cả những gì cần làm là có thể gửi đăng ký và xuất bản tin nhắn tới máy chủ và nhận các tin nhắn xuất bản từ máy chủ. Phần cứng một lần nữa sẽ là phần giao tiếp thực tế.


Postscript:

Tôi chưa bao giờ thực sự xây dựng được một hệ thống như vậy tự của tôi, tất cả những điều trên chỉ là trực tiếp của đỉnh đầu của tôi. Một lập trình viên có kinh nghiệm không cần nhiều hơn một vài giờ để thực hiện những điều cơ bản, có thể là một vài ngày cho một người thiếu kinh nghiệm.

Để liên lạc bạn có thể sử dụng, ví dụ: Boost ASIO, có thể sử dụng một threads mỗi kênh. Và bạn có thể sử dụng một cái gì đó như Boost property tree để tạo/phân tích cú pháp JSON hoặc XML thư.

Tuy nhiên, tất cả điều này là loại phát minh lại bánh xe, khi bạn có thể bắt đầu sử dụng một trong những hệ thống hiện có như RabbitMQ trong một vài giờ, tiết kiệm rất nhiều thời gian (và rất nhiều lỗi!)

+2

Tôi thứ hai là ý tưởng, nhưng chỉ khi "khung" bạn sắp xây dựng là siêu đơn giản và cần phải nhẹ, nếu không .. không phát minh lại bánh xe! Tôi đã xây dựng loại hệ thống này cho một dự án trong quá khứ, trong .NET, chỉ trong vài ngày, mọi thứ được bao gồm. Đó là niềm vui, và đã được blazing nhanh. Và vì nó rất kinh tế khi chúng tôi cần phải mở rộng quy mô, chúng tôi đã ném nó đi và thay thế nó mà không cần nhìn lại. Trong C++, tôi cũng sẽ sử dụng Boost. –

4

Theo như các máy chủ nhẹ đi, Redis hỗ trợ các lệnh pub/sub.

Bản thân mã Redis cực kỳ chặt chẽ (chỉ một vài tệp), nó đơn luồng (sử dụng vòng lặp sự kiện) và mức tiêu thụ bộ nhớ khá thấp (so với các hệ thống xếp hàng khác mà tôi đã thấy).

+1

Tôi thực sự thích Redis và đã sử dụng nó như một dịch vụ lưu trữ/lưu trữ trên một số dự án riêng tư. Chỉ cần tò mò nếu nó phù hợp trên một CPU nhỏ như PI mâm xôi? – Yoshi

+0

@Yoshi: so với bất kỳ hệ thống xếp hàng nào khác (ActiveMQ, RabbitMQ, HornetQ, ...), nó chắc chắn có khả năng phù hợp hơn. Tôi sẽ quan tâm nhiều hơn đến RAM, nhưng bạn luôn có thể loại bỏ Lua JIT vv ... để có được một quá trình nhẹ hơn. –

+0

Có vẻ như redis chỉ tốt cho các tin nhắn văn bản. Điều gì về nhị phân? – liuyanghejerry

3

Tôi biết đã muộn nhưng có thể hữu ích cho người khác. Tôi đã thực hiện một pub/sub cơ bản trong C++ bằng cách sử dụng boost.

CppPubSub

Cách sử dụng rất đơn giản. Từ một đầu xuất bản dữ liệu của bạn (bản đồ chung) trên kênh và phía bên kia đăng ký kênh giống nhau và nhận lại bản đồ chung.

// you should create a singleton object of NotificationService class, make it accessible throughout your application. 
INotificationService* pNotificationService = new NotificationService(); 

// Subscribe for the event. 
function<NotificationHandler> fnNotificationHandler = bind(&SubscriberClass::NotificationHandlerFunction, this, std::placeholders::_1); 
subscriptionToken = pNotificationService->Subscribe("TEST_CHANEL", fnNotificationHandler); 

// Publish event 
NotificationData _data; 
_data["data1"] = "Hello"; 
_data["data2"] = "World"; 
pNotificationService->Publish("TEST_CHANEL", _data); 

// Unsubscribe event. 
pNotificationService->Unsubscribe(subscriptionToken); 
Các vấn đề liên quan