2010-10-24 26 views
7

Trước hết, tôi có ý định không thù địch cũng không nản chí, chỉ muốn biết suy nghĩ của mọi người. Tôi đang tìm kiếm thông tin liên lạc hai chiều giữa khách hàng và máy chủ; khách hàng là một ứng dụng web. Tại thời điểm này, tôi có một vài tùy chọn: liên kết hai chiều độc quyền MS, từ những gì tôi nghe không đáng tin cậy và không tự nhiên: sao chổi và ổ cắm web (đối với các trình duyệt được hỗ trợ).Tại sao Ổ cắm web không sử dụng SOAP?

Tôi biết câu hỏi này đã được hỏi theo những cách khác ở đây, nhưng tôi có một câu hỏi cụ thể hơn cho cách tiếp cận này. Xem xét các ổ cắm web là phía máy khách, mã máy khách nằm trong JavaScript. Có thực sự là ý định xây dựng một đoạn lớn ứng dụng trực tiếp trong JavaScript không? Tại sao W3C không làm điều này trong các dịch vụ web? Sẽ không dễ dàng hơn nếu chúng ta có thể sử dụng SOAP để cung cấp một hợp đồng và xác định các sự kiện cùng với thông điệp hiện có liên quan? Chỉ cần cảm thấy như đầu ngắn của thanh cho đến nay.

Tại sao không làm cho nó đơn giản và tận dụng tính năng động JS và để lại phần lớn mã mà nó thuộc về .... trên máy chủ?

Thay vì

mysocket.send("AFunction|withparameters|segmented"); 

chúng ta có thể nói

myServerObject.AFunction("that", "makessense"); 

và thay vì

... 
mysocket.onmessage = function() { alert("yay! an ambiguous message"); } 
... 

chúng ta có thể nói

... 
myServerObject.MeaningfulEvent = function(realData) { alert("Since I have realistic data...."); alert("Hello " + realData.FullName); } 
... 

HTML 5 mất mãi mãi để giữ ... chúng tôi đã lãng phí một lượng lớn nỗ lực theo hướng sai? Suy nghĩ?

Trả lời

18

Âm thanh với tôi như bạn chưa nắm bắt đầy đủ các khái niệm xung quanh Websockets. Ví dụ bạn nói:

Xét cổng web là client-side

Đây không phải là trường hợp, ổ cắm có 2 mặt, bạn có thể nghĩ này như một Server và Client, tuy nhiên một khi kết nối được thiết lập sự phân biệt làm mờ - bạn có thể nghĩ về máy khách và máy chủ là "đồng nghiệp" - mỗi người có thể viết hoặc đọc vào đường ống kết nối chúng (kết nối ổ cắm) bất cứ lúc nào. Tôi nghi ngờ bạn sẽ được hưởng lợi từ việc học thêm một chút về HTTP hoạt động trên đầu trang của TCP - WebSockets là tương tự/tương tự như HTTP theo cách này.

Về SOAP/WSDL, từ quan điểm của cuộc hội thoại xung quanh TCP/WebSocket/HTTP, bạn có thể nghĩ về tất cả các cuộc hội thoại SOAP/WSDL giống với HTTP (tức là lưu lượng truy cập trang web bình thường).

Cuối cùng, hãy nhớ tính chất xếp chồng lên nhau của lập trình mạng, ví dụ SOAP/WSDL trông như thế này:

SOAP/WSDL 
--------- (sits atop) 
HTTP 
--------- (sits atop) 
TCP 

Và WebSockets trông giống như

WebSocket 
--------- (sits atop) 
TCP 

HTH này.

+0

tại sao điều này lại bị giảm giá? – Anurag

+5

Vâng, phần xếp chồng không hoàn toàn đúng. Mặc dù SOAP trong hầu hết các trường hợp được gửi qua HTTP, WSDL cho phép xác định các ràng buộc tùy ý. Vì WSDL có khả năng mở rộng rất nhiều theo thiết kế, nên có thể định nghĩa và thực thi SOAP qua ràng buộc Websockets. Bằng cách đó, nó sẽ là SOAP -> Websocket -> TCP, trong đó SOAP chỉ là định dạng mã hóa thư. Ngay cả trong ví dụ được phác họa trong câu trả lời này, dữ liệu được gửi qua websocket hầu hết được mã hóa bằng cách nào đó, ví dụ: dưới dạng JSON. Vì vậy, sự tương tự chính xác sẽ là JSON -> Websocket -> TCP vs SOAP -> Websocket -> TCP vs SOAP -> HTTP -> TCP. – vanto

+0

@vanto có bất kỳ chuẩn mã hóa JSON nào cho "JSON trên WebSocket trên TCP" không? Một cái gì đó tương tự như những gì SOAP đã làm với XML? –

1

WebSocket làm cho Comet và tất cả các kỹ thuật loại đẩy HTTP khác dễ đọc bằng cách cho phép yêu cầu bắt nguồn từ máy chủ. Đó là loại ổ cắm có hộp cát và cho chúng ta chức năng giới hạn.

Tuy nhiên, API là đủ chung để các tác giả khung và thư viện cải thiện giao diện theo bất kỳ cách nào họ muốn. Ví dụ, bạn có thể viết một số dịch vụ RPC hoặc RMI theo kiểu trên WebSockets cho phép gửi các đối tượng qua dây. Bây giờ nội bộ họ đang được đăng trên một số định dạng không xác định, nhưng người dùng dịch vụ không cần phải biết và không quan tâm.

Vì vậy, suy nghĩ từ một tác giả đặc tả POV, đi từ

mysocket.send("AFunction|withparameters|segmented"); 

để

myServerObject.AFunction("that", "makessense"); 

là tương đối dễ dàng và đòi hỏi phải viết một wrapper nhỏ xung quanh WebSockets để serialization và deserialization xảy ra opaquely đến các ứng dụng . Nhưng đi theo hướng ngược lại có nghĩa là các tác giả đặc tả cần tạo ra một API phức tạp hơn nhiều, làm cho nền tảng yếu hơn cho việc viết mã lên trên nó.

3

JavaScript cho phép khách hàng giao tiếp qua HTTP với XMLHttpRequest. WebSockets mở rộng chức năng này để cho phép JavaScript tạo ra I/O mạng tùy ý (không chỉ HTTP), là phần mở rộng hợp lý và cho phép tất cả các loại ứng dụng cần sử dụng lưu lượng TCP (nhưng có thể không sử dụng giao thức HTTP) sang JavaScript. Tôi nghĩ nó khá hợp lý khi các ứng dụng tiếp tục chuyển sang đám mây, HTML và JavaScript hỗ trợ mọi thứ có sẵn trên màn hình nền.

Mặc dù máy chủ có thể thực hiện I/O mạng không phải HTTP thay mặt cho máy khách JavaScript và thực hiện giao tiếp đó qua HTTP, nhưng đây không phải là điều phù hợp hoặc hiệu quả nhất. Ví dụ, nó sẽ không có ý nghĩa để thêm một chi phí chuyến đi vòng bổ sung khi cố gắng để làm cho một thiết bị đầu cuối SSH trực tuyến. WebSockets giúp JavaScript có thể nói trực tiếp với máy chủ SSH.

Đối với cú pháp, một phần của nó dựa trên XMLHttpRequest. Như đã được chỉ ra trong bài viết khác, WebSockets là một API khá thấp có thể được gói trong một cái dễ hiểu hơn. Điều quan trọng hơn là WebSockets hỗ trợ tất cả các ứng dụng cần thiết hơn là nó có cú pháp thanh lịch nhất (đôi khi tập trung vào cú pháp có thể dẫn đến chức năng hạn chế hơn). Các tác giả thư viện luôn có thể làm cho API rất chung này dễ quản lý hơn đối với các nhà phát triển ứng dụng khác.

+0

Bạn không thể kết nối trực tiếp với ổ cắm thô bằng cách sử dụng WebSockets (có một cái bắt tay và hai byte khung). Dự án NoVNC của tôi bao gồm 'wsproxy' (http://github.com/kanaka/noVNC/tree/master/utils/) rằng proxy giữa WebSockets và ổ cắm TCP thô. – kanaka

3

Như bạn đã lưu ý, WebSockets có chi phí thấp. Chi phí tương tự như các cổng TCP thông thường: chỉ cần thêm hai byte cho mỗi khung so với hàng trăm cho AJAX/Comet.

Tại sao mức độ thấp thay vì một số chức năng RPC tích hợp? Một số suy nghĩ:

  • Nó không phải là khó khăn để có một giao thức RPC hiện có và lớp nó trên một giao thức ổ cắm ở mức độ thấp. Bạn không thể đi theo hướng ngược lại và xây dựng một kết nối cấp thấp nếu giả sử RPC.

  • Hỗ trợ WebSockets là khá tầm thường để thêm vào nhiều ngôn ngữ ở phía máy chủ. Tải trọng chỉ là một chuỗi UTF-8 và khá nhiều ngôn ngữ có hỗ trợ hiệu quả tích hợp cho điều đó. Một cơ chế RPC không quá nhiều. Làm thế nào để bạn xử lý các chuyển đổi kiểu dữ liệu giữa Javascript và ngôn ngữ đích? Bạn có cần thêm gợi ý kiểu ở phía bên Javascript không? Điều gì về các đối số độ dài biến và/hoặc danh sách đối số? Bạn có xây dựng những cơ chế này nếu ngôn ngữ không có câu trả lời hay không? Vv

  • Cơ chế RPC nào sẽ được mô hình sau? Bạn có chọn một cái hiện có (SOAP, XML-RPC, JSON-RPC, RMI Java, AMF, RPyC, CORBA) hoặc một cái mới hoàn toàn không?

  • Sau khi hỗ trợ khách hàng khá phổ biến, sau đó nhiều dịch vụ có ổ cắm TCP bình thường sẽ thêm hỗ trợ WebSockets (vì nó khá tầm thường để thêm). Điều này cũng không đúng nếu WebSockets được dựa trên RPC. Một số dịch vụ hiện có có thể thêm một lớp RPC, nhưng đối với hầu hết các dịch vụ WebSockets phần lớn sẽ được tạo từ đầu.

Đối noVNC dự án (VNC client chỉ sử dụng Javascript, Canvas, WebSockets) của tôi về bản chất thấp overhead của WebSockets là rất quan trọng để đạt được hiệu suất hợp lý. Cho đến khi các máy chủ VNC bao gồm hỗ trợ WebSockets, noVNC bao gồm wsproxy là một WebSockets chung cho proxy cổng TCP.

Nếu bạn đang suy nghĩ về việc triển khai ứng dụng web tương tác và bạn chưa quyết định ngôn ngữ phía máy chủ, tôi khuyên bạn nên xem Socket.IO là thư viện cho node (Javascript phía máy chủ bằng công cụ V8 của Google).

Ngoài tất cả các ưu điểm của nút (cùng ngôn ngữ trên cả hai mặt, thư viện nguồn rất hiệu quả, v.v.), Ổ cắm.IO cung cấp cho bạn một số điều:

  • Cung cấp cả thư viện khung máy khách và máy chủ để xử lý các kết nối.

  • Phát hiện phương tiện giao thông tốt nhất được hỗ trợ bởi cả khách hàng và máy chủ. Giao thông vận tải bao gồm (từ tốt nhất đến tồi tệ nhất): WebSockets gốc, WebSockets sử dụng mô phỏng flash, các mô hình AJAX khác nhau.

  • Giao diện nhất quán cho dù giao thông được sử dụng là gì.

  • Tự động mã hóa/giải mã các kiểu dữ liệu Javascript.

Sẽ không khó để tạo cơ chế RPC trên đỉnh Socket.IO vì cả hai bên đều có cùng ngôn ngữ với cùng loại gốc.

0

Tôi chạy vào cùng một vấn đề mà tôi cần phải làm một cái gì đó như call('AFunction', 'foo', 'bar') thay vì serialize/de-serialize mọi tương tác. Sở thích của tôi cũng là để lại phần lớn mã trên máy chủ và chỉ sử dụng Javascript để xử lý chế độ xem. WebSockets phù hợp hơn vì nó hỗ trợ tự nhiên cho truyền thông hai hướng. Để đơn giản hóa việc phát triển ứng dụng của tôi, tôi tạo một lớp trên đầu trang của WebSockets để thực hiện các cuộc gọi phương thức từ xa (như RPC).

Tôi đã xuất bản thư viện RMI/RPC tại http://sourceforge.net/projects/rmiwebsocket/. Khi giao tiếp được thiết lập giữa trang web và servlet, bạn có thể thực hiện các cuộc gọi theo một trong hai hướng. Máy chủ sử dụng sự phản chiếu để gọi phương thức thích hợp trong đối tượng phía máy chủ và máy khách sử dụng phương thức 'call' của Javascript để gọi hàm thích hợp trong đối tượng phía máy khách. Thư viện sử dụng Jackson để quản lý tuần tự hóa/deserialization của các loại Java khác nhau đến/từ JSON.

0

WebSocket JSR được thương lượng bởi một số bên (Oracle, Apache, Eclipse, v.v.) tất cả với các chương trình nghị sự rất khác nhau.Nó cũng giống như họ dừng lại ở mức độ vận chuyển tin nhắn và để lại các cấu trúc mức cao hơn. Nếu những gì bạn cần là Java với JavaScript RMI, hãy xem FERMI Framework.

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