2017-02-07 17 views
5

Vì vậy, tôi đang chạy một Ratchet (php) máy chủ WebSocket với nhiều tuyến đường kết nối làm nhiều ứng dụng Ratchet (MessageComponentInterfaces):Gửi tin nhắn từ PHP kịch bản cho nhiều ứng dụng Ratchet WebSocket (thông qua ZMQ socket)

//loop 
$loop = \React\EventLoop\Factory::create(); 

//websocket app 
$app = new Ratchet\App('ws://www.websocketserver.com', 8080, '0.0.0.0', $loop); 

/* 
* load routes 
*/ 
$routeOne = '/example/route'; 
$routeOneApp = new RouteOneApp(); 
$app->route($routeOne, $routeOneApp, array('*')); 

$routeTwo = '/another/route'; 
$routeTwoApp = new AnotherApp(); 
$app->route($routeTwo, $routeTwoApp, array('*')); 

Từ đây tôi ràng buộc một socket ZMQ, để có thể nhận được các tin nhắn được gửi từ các script php chạy trên máy chủ apache bình thường.

// Listen for the web server to make a ZeroMQ push after an ajax request 
$context = new \React\ZMQ\Context($loop); 
$pull = $context->getSocket(\ZMQ::SOCKET_PULL); 
$pull->bind('tcp://127.0.0.1:5050'); // Binding to 127.0.0.1 means the only client that can connect is itself 
$pull->on('message', array($routeOneApp, 'onServerMessage')); 

Cuối cùng, máy chủ được bắt đầu:

//run 
$loop->run(); 

này hoạt động hoàn toàn tốt đẹp miễn là tôi đang chỉ ràng buộc một trong những ứng dụng ratchet sử dụng socket ZMQ. Tuy nhiên, tôi muốn có thể gửi tin nhắn riêng cho cả hai ứng dụng Ratchet. Với mục đích này tôi nghĩ đến việc ràng buộc hai ổ cắm ZMQ để tuyến đường khác nhau thích:

$pullOne->bind('tcp://127.0.0.1:5050' . $routeOne); // Binding to 127.0.0.1 means the only client that can connect is itself 
$pullOne->on('message', array($routeOneApp, 'onServerMessage')); 

$pullTwo->bind('tcp://127.0.0.1:5050' . $routeTwo); // Binding to 127.0.0.1 means the only client that can connect is itself 
$pullTwo->on('message', array($routeTwoApp, 'onServerMessage')); 

Tuy nhiên, điều này dẫn đến một thông báo lỗi từ ZMQ khi ràng buộc các ổ cắm thứ hai, nói địa chỉ cho đã được sử dụng.

Vì vậy, câu hỏi đặt ra là có cách nào khác để sử dụng các tuyến trên ổ cắm ZMQ không? Hoặc tôi có nên sử dụng các phương tiện khác để phân biệt giữa các tin nhắn cho các ứng dụng Ratchet riêng biệt, và nếu có, giải pháp tốt là gì? Tôi nghĩ về việc liên kết với 2 cổng khác nhau, nhưng tôi nghĩ rằng đó sẽ là một giải pháp khá xấu xí ?!

+0

bạn có chắc chắn muốn liên kết() khi ở trong PULL không? Thông thường trong ZMQ bên PUSH liên kết(), phía PULL kết nối(). – Jack

+0

câu hỏi hay, tôi sao chép các ràng buộc từ một số hướng dẫn tôi tìm thấy trên internet và nó có vẻ làm việc. Tôi sẽ có một cái nhìn nếu connect() hoạt động tốt. –

Trả lời

2

Nói chung trong các gói TCP được xác định bởi 4 bộ (ip người gửi, cổng người gửi, người nhận ip, cổng thu).

Khi gói đến đến lớp mạng, nó được chuyển tiếp đến ứng dụng thích hợp bằng cách xem ip và cổng người nhận. Nếu bạn sử dụng cùng một cặp cho cả hai ứng dụng, lớp sẽ không thể quyết định ai sẽ gửi nó đến khi có kết nối.

Một giải pháp sẽ là kết nối một kết nối đơn và viết trình xử lý thông thường xem xét nội dung đến và sau đó quyết định (Tôi giả sử bạn có một số logic) để phân biệt các kết nối đến với các phiên bản khác nhau và sau đó gọi trình xử lý tương ứng. Trình xử lý có thể lấy đối tượng kết nối và có thể xử lý kết nối đó.

Nếu cả hai trường hợp của bạn là giống nhau và không quan trọng ai nhận được yêu cầu thì bạn chỉ có thể ngẫu nhiên chuyển tiếp kết nối mới cho bất kỳ trình xử lý nào.

Chỉnh sửa: Tôi đã cố gắng trả lời câu hỏi bất kể loại ứng dụng (Racket/ZMQ vv) vì vấn đề bạn đang cố gắng giải quyết là vấn đề cơ bản đối với bất kỳ ứng dụng mạng nào. Đối với trường hợp này vì bạn có hai ứng dụng đang chạy và muốn nghe trên cùng một cổng, bạn có thể có một trình xử lý chung có thể xem URL yêu cầu và chuyển tiếp kết nối đến trình xử lý thích hợp.

URL yêu cầu có thể thu được bằng

$querystring = $conn->WebSocket->request->getQuery(); 

Bây giờ khách hàng có thể kết nối sử dụng

ws://localhost:5050/app1 
and 
ws://localhost:5050/app2 

ứng dụng khác nhau của bạn bây giờ có thể xử lý những kết nối riêng biệt.

+0

Điều khiến tôi đặt câu hỏi là thực tế là Ratchet sử dụng nhiều "ứng dụng" mà tất cả đều bị ràng buộc vào cùng một cổng. Rõ ràng tất cả chúng đều kết nối với cùng một websocket và được gửi xung quanh bằng cách sử dụng ID hoặc một số phương pháp khác. Trong thực tế, sẽ gần như tốt hơn khi viết giao thức JSON của riêng bạn để gửi các thông báo dựa trên AppID hoặc một cái gì đó tương tự, nhưng có vẻ như đã có một phương pháp cho điều này và tài liệu Ratchet nghèo nàn không phác thảo tốt. – user1274820

+0

Khi bạn nói nhiều "ứng dụng", điều đó có nghĩa là bạn đang nói về lớp ứng dụng. Nó đồng nghĩa với việc có nhiều mô-đun bên trong một máy chủ http như apache. Bạn cần một số ID (như bạn đã đề cập) để phân biệt các yêu cầu cho các ứng dụng khác nhau. Trong trường hợp máy chủ HTTP, URL này được thực hiện bởi URL. Nếu tài liệu của Rachet không tài liệu tốt, thì sẽ tốt hơn nếu bạn thực hiện giao thức riêng của mình trên kết nối được cung cấp bởi Rachet. –

+0

Bạn không nhất thiết phải chuyển sang JSON. Hãy nhớ rằng các kết nối Websocket cũng bắt đầu như các kết nối HTTP thông thường. Vì vậy, bạn có thể sử dụng URL để phân biệt. Bạn sẽ phải tìm cách trong tài liệu để lấy URL được sử dụng cho việc bắt tay websocket. Đó là nếu Rachet tiếp cận điều đó. –

Các vấn đề liên quan