2016-08-08 14 views
18

Tôi đã nhận được một ứng dụng Web, được triển khai bằng Spring sử dụng STOMP qua Nhắn tin WebSockets, tương tự như mô tả here (với RabbitMQ ở phần cuối). Nó chạy trên Tomcat và tôi có thể kết nối với ứng dụng bằng các URL thông thường (ví dụ: http://host/server/). Tôi cũng đã được đưa ra một khách hàng demo - một trang JSPX, sử dụng Modernizr WebSockets và SockJS. Mã kết nối trong trình khách demo giống như sau:Kết nối với Stomp qua WebSockets được triển khai bằng Spring 4 từ máy khách Java

if (Modernizr.websockets) { 
    socket = new WebSocket('ws://host/server/endpointx'); 
} 
else { 
    socket = new SockJS('/server/endpointy'); 
} 

stompClient = Stomp.over(socket); 
stompClient.connect(headers, function(frame) { ... }); 
.... 

Trình khách demo hoạt động tốt (khi tôi tải trang JSPX trong trình duyệt, tôi có thể kết nối với máy chủ). Nhưng mục tiêu của tôi là kết nối với cùng một máy chủ bằng cách sử dụng một số thư viện Java STOMP. Vấn đề là, các thư viện tôi đã cố gắng, yêu cầu chủcổng như các thông số kết nối: Ví dụ với ActiveMQ Stomp library:

StompConnection connection = new StompConnection(); 
connection.open("host", port); 
connection.connect(new HashMap<String, String>()); 

Nếu tôi chỉ định port như 61613, kết nối thành công, nhưng tôi nhấn RabbitMQ trực tiếp, không phải của tôi máy chủ (đây không phải là những gì tôi muốn). Nếu tôi chỉ định 8080 (hoặc 80), kết nối tôi nhận được một lỗi

java.io.EOFException tại java.io.DataInputStream.readByte (Unknown Source) tại org.apache.activemq.transport.stomp .StompWireFormat.unmarshal (StompWireFormat.java:137) tại org.apache.activemq.transport.stomp.StompConnection.receive (StompConnection.java:77) tại org.apache.activemq.transport.stomp.StompConnection.receive (StompConnection .java: 68) tại org.apache.activemq.transport.stomp.StompConnection.connect (StompConnection.java:139) tại .... stomp.impl.activemq.ActiveMQStompDriver.connect (ActiveMQStompDriver.java:39) ... 25 hơn

và dấu vết cho thấy rằng điều này là do CONNECT khung không bao giờ nhận được một dự kiến ​​CONNECTED khung (trong thực tế, nó không nhận được bất cứ điều gì trở lại).

Vì vậy, tôi bối rối: tôi đang sử dụng cổng sai? hoặc đối phó với một số thư viện không tương thích? hay tôi cần bằng cách nào đó chỉ ra Tomcat mà tôi muốn upgrade HTTP connection to WebSockets?

Nếu câu hỏi trên khó trả lời, thì câu hỏi này hữu ích như nhau: làm cách nào để kết nối với ứng dụng Spring với STOMP qua kênh nhắn tin WebSockets chạy trên Tomcat bằng Java?

Trả lời

0

Tôi đã nhận được một ứng dụng web, được triển khai bằng Spring sử dụng STOMP qua Nhắn tin WebSockets, tương tự như những gì được mô tả ở đây (với RabbitMQ ở phần cuối). Nó chạy trên Tomcat và tôi có thể kết nối với ứng dụng bằng các URL thông thường (ví dụ: http://host/server/).

Đây chỉ là để tham khảo sau này trong câu trả lời:

Browser -> WebSocket -> Spring STOMP Broker Relay -> RabbitMQ 

Ví dụ làm việc tạo ra một khách hàng javscript trong trình duyệt của người dùng cuối. Nó kết nối qua WebSockets với máy chủ Tomcat của bạn & Chuyển tiếp môi giới STOMP Spring trong ứng dụng của bạn. Tiếp sức, như tên gọi của nó, chuyển tiếp các thông điệp STOMP mà nó nhận được thông qua WebSocket đến một ổ cắm thực tế được kết nối với RabbitMQ (cũng thông qua STOMP).

Tôi cũng được cung cấp một ứng dụng trình diễn - một trang JSPX, sử dụng Modernizr WebSockets và SockJS.

Không liên quan đến câu trả lời nhưng bạn không cần kiểm tra xem WebSockets có được hỗ trợ trong trình duyệt của khách hàng hay không. SockJS sẽ làm điều này cho bạn và tự động chọn kênh tốt nhất để sử dụng. Trong bất kỳ trình duyệt hiện đại nào không phải là một proxy hạn chế, đó sẽ là WebSockets.

Nhưng mục tiêu của tôi là kết nối với cùng một máy chủ bằng cách sử dụng một số thư viện Java STOMP. Vấn đề là, các thư viện tôi đã thử, yêu cầu máy chủ và cổng làm thông số kết nối

Tôi nghi ngờ một máy khách Java STOMP sẽ được thiết kế để hoạt động trong trường hợp này (mặc dù có thể). Thông thường, một máy khách Java STOMP sẽ chạy phía máy chủ hoặc một nơi nào đó mà nó sẽ chỉ kết nối trực tiếp với máy chủ STOMP, trong trường hợp của bạn có nghĩa là kết nối trực tiếp với RabbitMQ.

Bạn đã đề cập đến việc có thể kết nối trực tiếp với Thỏ, vì vậy đó sẽ là một giải pháp khả thi ở đây (bạn nói bạn không muốn làm điều này, nhưng không phải lý do tại sao, vui lòng làm rõ điểm đó trong nhận xét). Nếu mã của bạn đang chạy ở phía máy chủ, thì đây chắc chắn là con đường để đi. Đi qua một kênh WebSocket và relay môi giới mùa xuân sẽ chỉ thêm một hop bổ sung và độ trễ không cần thiết.

Một giải pháp khác là sử dụng ứng dụng khách Java có thể giao tiếp qua WebSockets & STOMP. Tôi sẽ chỉ khuyên bạn nên điều này nếu mã Java của bạn đang chạy như một khách hàng từ xa ở đâu đó và nó sẽ không có quyền truy cập để nói chuyện trực tiếp với RabbitMQ.

Vì vậy, tôi bối rối: tôi đang sử dụng cổng sai? hoặc đối phó với một số thư viện không tương thích? hoặc tôi cần phải bằng cách nào đó chỉ ra Tomcat rằng tôi muốn nâng cấp kết nối HTTP đến WebSockets?

61613 là cổng phù hợp để liên lạc trực tiếp với RabbitMQ nếu đó là những gì bạn muốn làm. Cổng để thiết lập kết nối WebSocket chỉ là cổng HTTP hoặc HTTPS chuẩn mà Tomcat đang nghe kết nối (mặc định là 8080/8443). Bạn không thể nói STOMP trực tiếp với Tomcat, nó không hiểu giao thức đó. Bạn phải khởi tạo một kết nối WebSocket và sau đó nói STOMP cho ứng dụng của bạn (tức là relay nhà môi giới STOMP của Spring).

Để thực hiện việc này, bạn cần một khách hàng biết cách nói WebSocket & một khách hàng có thể nói STOMP qua kênh WebSocket. Máy khách hiện tại của bạn đang cố gắng tạo một kết nối socket thông thường tới Tomcat và không phải là kết nối WebSocket. Để thành công, nó sẽ cần phải bắt đầu một kết nối WebSocket sau đó gửi các thông điệp STOMP qua kết nối WebSocket.

Khi demo của bạn chạy trong trình duyệt, kết nối WebSocket được xử lý bởi trình duyệt của bạn và SockJS, và trình khách Javascript STOMP của bạn nói về kết nối WebSocket với ứng dụng thông qua STOMP (xem sơ đồ ASCII ở trên).

Nếu câu hỏi trên khó trả lời, thì cách này hữu ích như nhau: làm cách nào để kết nối với ứng dụng Spring với STOMP qua kênh nhắn tin WebSockets chạy trên Tomcat bằng Java?

Tôi không nghĩ bạn thường muốn làm điều này.Nếu bạn có mã Java chạy trên Tomcat, sẽ hiệu quả hơn khi kết nối trực tiếp với RabbitMQ (tức là máy chủ STOMP) của bạn với máy khách Java STOMP của bạn.

STOMP qua WebSockets chủ yếu để các trình khách dựa trên trình duyệt chạy từ xa có thể kết nối và gửi tin nhắn dễ dàng và an toàn mà không cần truy cập trực tiếp vào máy chủ RabbitMQ của bạn.

Hy vọng điều đó sẽ hữu ích!

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