API Websocket để thay thế API REST?


101

Tôi có một ứng dụng có chức năng chính hoạt động trong thời gian thực, thông qua websockets hoặc bỏ phiếu dài.

Tuy nhiên, hầu hết trang web được viết theo kiểu RESTful, rất phù hợp cho các ứng dụng và các khách hàng khác trong tương lai. Tuy nhiên, tôi đang nghĩ đến việc chuyển đổi sang API websocket cho tất cả các chức năng của trang web, tránh xa REST. Điều đó sẽ giúp tôi dễ dàng tích hợp các tính năng thời gian thực vào tất cả các phần của trang web. Điều này có gây khó khăn hơn cho việc xây dựng ứng dụng hoặc ứng dụng khách di động không?

Tôi thấy rằng một số người đã làm những thứ như thế này: SocketStream


2
Cuộc thăm dò dài @Stegi hoạt động đủ tốt như một dự phòng, không quá lo lắng về điều đó.
Harry,

2
Harry bây giờ sau 7 năm, nó làm việc với bạn như thế nào? Tự hỏi, vì tôi cũng muốn chuyển sang hướng đó. @Harry
Dmitry Kudryavtsev

2
@DmitryKudryavtsev Tôi đã không làm như vậy. Phương pháp truyền thống hiệu quả với tôi và không khó hơn nhiều.
Harry

Câu trả lời:


97

Không phải nói rằng những câu trả lời khác ở đây không có giá trị, chúng tạo ra một số điểm tốt. Nhưng tôi sẽ đi ngược lại sự đồng thuận chung và đồng ý với bạn rằng việc chuyển sang websockets để có nhiều hơn các tính năng thời gian thực là rất hấp dẫn.

Tôi đang nghiêm túc xem xét việc chuyển ứng dụng của mình từ kiến ​​trúc RESTful sang nhiều kiểu RPC hơn thông qua websockets. Đây không phải là một "ứng dụng đồ chơi" và tôi không chỉ nói về các tính năng thời gian thực, vì vậy tôi có đặt trước. Nhưng tôi thấy nhiều lợi ích khi đi theo con đường này và cảm thấy nó có thể trở thành một giải pháp đặc biệt.

Kế hoạch của tôi là sử dụng DNode , SocketIOBackbone . Với những công cụ này, các mô hình và bộ sưu tập Backbone của tôi có thể được chuyển từ / đến máy khách và máy chủ bằng cách chỉ cần gọi một hàm kiểu RPC. Không còn quản lý các điểm cuối REST, tuần tự hóa / giải mã hóa các đối tượng, v.v. Tôi chưa làm việc với socketstream, nhưng nó có vẻ đáng để thử.

Tôi vẫn còn một chặng đường dài trước khi có thể chắc chắn nói rằng đây là một giải pháp tốt và tôi chắc chắn rằng nó không phải là giải pháp tốt nhất cho mọi ứng dụng, nhưng tôi tin rằng sự kết hợp này sẽ đặc biệt mạnh mẽ. Tôi thừa nhận rằng có một số hạn chế, chẳng hạn như mất khả năng lưu trữ tài nguyên bộ nhớ cache. Nhưng tôi có cảm giác những lợi thế sẽ vượt trội hơn chúng.

Tôi muốn theo dõi quá trình khám phá loại giải pháp này của bạn. Nếu bạn có bất kỳ thử nghiệm github nào, vui lòng chỉ cho tôi. Tôi chưa có bất kỳ, nhưng hy vọng sẽ sớm.

Dưới đây là danh sách các liên kết để đọc sau mà tôi đã thu thập. Tôi không thể đảm bảo rằng tất cả chúng đều đáng giá, vì tôi chỉ lướt qua nhiều trong số chúng. Nhưng hy vọng một số sẽ giúp ích.


Hướng dẫn tuyệt vời về cách sử dụng Socket.IO với Express. Nó hiển thị các phiên cấp tốc cho socket.io và thảo luận về cách có các phòng khác nhau cho từng người dùng được xác thực.

Hướng dẫn về node.js / socket.io / backbone.js / express / connect / jade / redis với xác thực, lưu trữ Joyent, v.v.:

Hướng dẫn sử dụng Pusher với Backbone.js (sử dụng Rails):

Xây dựng ứng dụng với backbone.js trên máy khách và node.js với express, socket.io, dnode trên máy chủ.

Sử dụng Backbone với DNode:


1
Tôi vừa trả lời một câu hỏi liên quan và kèm theo một vài suy nghĩ khác: stackoverflow.com/questions/4848642/…
Tauren

11
“Tôi vẫn còn một chặng đường dài phía trước trước khi có thể dứt khoát nói rằng đây là một giải pháp tốt” - Chỉ tò mò, đây có thực sự là một giải pháp tốt? : D
inf3rno 27/12/13

7
Vui lòng phản hồi @Tauren. Tôi rất quan tâm đến những gì bạn phải nói bây giờ.
No_name

4
@Tauren Tôi cũng tò mò không biết điều này diễn ra như thế nào?
Kurren

57

HTTP REST và WebSockets rất khác nhau. HTTP là không trạng thái , vì vậy máy chủ web không cần biết bất cứ điều gì và bạn nhận được bộ nhớ đệm trong trình duyệt web và trong proxy. Nếu bạn sử dụng WebSockets, máy chủ của bạn đang trở nên trạng thái và bạn cần có kết nối với máy khách trên máy chủ.

Giao tiếp Yêu cầu-Trả lời so với Đẩy

Chỉ sử dụng WebSockets nếu bạn cần PUSH dữ liệu từ máy chủ đến máy khách, mẫu giao tiếp đó không được bao gồm trong HTTP (chỉ theo cách giải quyết). PUSH rất hữu ích nếu các sự kiện được tạo bởi các máy khách khác cần phải có sẵn cho các máy khách được kết nối khác, ví dụ như trong các trò chơi mà người dùng phải hành động theo hành vi của máy khách khác. Hoặc nếu trang web của bạn đang theo dõi một cái gì đó, nơi máy chủ đẩy dữ liệu đến máy khách mọi lúc, ví dụ như thị trường chứng khoán (trực tiếp).

Nếu bạn không cần PUSH dữ liệu từ máy chủ, việc sử dụng máy chủ REST HTTP không trạng thái thường dễ dàng hơn. HTTP sử dụng một mẫu giao tiếp Yêu cầu-Trả lời đơn giản .


5
Chúng tôi rất quen với mô hình một hướng vì chúng tôi chưa từng có bất kỳ lựa chọn thay thế nào trước đây. Nhưng bây giờ khi ứng dụng của tôi ngày càng phát triển, tôi càng thấy rõ rằng càng có nhiều nơi sử dụng công nghệ đẩy thì càng phản hồi nhanh và ứng dụng càng trở nên hấp dẫn hơn.
Harry

Ứng dụng của tôi hiển thị danh sách bạn bè và số điểm họ có chẳng hạn. Tại sao không cập nhật nó trong thời gian thực. Nếu người dùng có thể thấy bạn bè của họ tiến bộ thì họ có thể có xu hướng muốn bắt kịp. Tôi có một số mô hình tài liệu nhất định mặc dù không được thay đổi chính xác thường xuyên, nhưng được thay đổi đủ để không cập nhật nó trong thời gian thực có thể gây ra nhầm lẫn nhỏ. Tại một thời điểm nào đó, trang web của bạn có đủ lợi ích từ việc có các bản cập nhật đẩy mà bạn bắt đầu xem mã của mình và một nửa là về REST và nửa còn lại là về các ổ cắm và bạn nói tốt, tôi muốn thống nhất điều này.
Harry

3
Đây là một tùy chọn chỉ sử dụng websockets để đẩy thông báo / lệnh vào ứng dụng web của bạn (như getUpdate hoặc refreshObjectWithId với các tham số). Lệnh này có thể được phân tích trong ứng dụng web của bạn (ứng dụng khách) và theo sau là yêu cầu nghỉ ngơi để lấy dữ liệu cụ thể thay vì tự vận chuyển dữ liệu qua websockets.
Beachwalker

2
Có rất nhiều lý do khiến websockets có thể dễ dàng hơn lệnh gọi REST - không chỉ để thúc đẩy. websocket.org/quantum.html
BT

WebSockets thật tuyệt vời và miễn phí máy chủ gửi dữ liệu máy khách bất kỳ lúc nào, không chỉ để phản hồi lại một tin nhắn của máy khách. WebSockets triển khai một giao thức dựa trên tin nhắn để khách hàng có thể nhận tin nhắn bất cứ lúc nào và nếu họ đang đợi một tin nhắn cụ thể, họ có thể xếp hàng đợi các tin nhắn khác để xử lý sau, sắp xếp lại các tin nhắn đã xếp hàng, bỏ qua các tin nhắn đã đẩy tùy thuộc vào trạng thái ứng dụng, v.v. Tôi ' Sẽ không bao giờ viết lại một ứng dụng dựa trên REST nữa. Flash cũng làm cho nó dễ dàng, với triển khai WebSocket dựa trên AS3 mã nguồn mở và dự phòng cho trình duyệt thông qua các phương thức ExternalInterface. (AddCallback / call).
Triynko

40

Tôi đang nghĩ đến việc chuyển đổi sang api WebSocket cho tất cả các chức năng của trang web

Không. Bạn không nên làm điều đó. Không có hại gì nếu bạn hỗ trợ cả hai mô hình. Sử dụng REST cho giao tiếp một chiều / yêu cầu đơn giản & WebSocket cho giao tiếp hai chiều, đặc biệt khi máy chủ muốn gửi thông báo thời gian thực.

WebSocket là một giao thức hiệu quả hơn RESTful HTTP nhưng vẫn RESTful HTTP điểm trên WebSocket trong bên dưới khu vực này.

  1. Tạo / Cập nhật / Xóa tài nguyên đã được xác định rõ cho HTTP. Bạn phải triển khai các hoạt động này ở mức thấp cho WebSockets.

  2. Các kết nối WebSocket mở rộng theo chiều dọc trên một máy chủ duy nhất trong đó các kết nối HTTP mở rộng theo chiều ngang. Có một số giải pháp độc quyền không dựa trên tiêu chuẩn cho tính năng mở rộng theo chiều ngang của WebSocket.

  3. HTTP đi kèm với rất nhiều tính năng tốt như bộ nhớ đệm, định tuyến, ghép kênh, gzipping, v.v. Những tính năng này phải được xây dựng trên Websocket nếu bạn chọn Websocket.

  4. Tối ưu hóa công cụ tìm kiếm hoạt động tốt cho các URL HTTP.

  5. Tất cả Proxy, DNS, firewall đều chưa nhận biết đầy đủ về lưu lượng WebSocket. Chúng cho phép cổng 80 nhưng có thể hạn chế lưu lượng bằng cách rình mò nó trước.

  6. Bảo mật với WebSocket là cách tiếp cận tất cả hoặc không có gì.

Hãy xem bài viết này để biết thêm chi tiết.


3
Đây là câu trả lời tốt nhất.
MattWeiler

1
Câu trả lời đầu cho chủ đề này
Sanandrea

10

Vấn đề duy nhất tôi có thể sử dụng TCP (WebSockets) làm chiến lược phân phối nội dung web chính của bạn là có rất ít tài liệu đọc trên mạng về cách thiết kế kiến ​​trúc và cơ sở hạ tầng trang web của bạn bằng TCP.

Vì vậy, bạn không thể học hỏi từ những sai lầm của người khác và sự phát triển sẽ chậm hơn. Đây cũng không phải là một chiến lược "đã thử và đã thử nghiệm".

Tất nhiên, bạn cũng sẽ mất tất cả các lợi thế của HTTP (Không có trạng thái và bộ nhớ đệm là những lợi thế lớn hơn).

Hãy nhớ rằng HTTP là một trừu tượng đối với TCP được thiết kế để phục vụ nội dung web.

Và đừng quên rằng SEO và công cụ tìm kiếm không làm websockets. Vì vậy, bạn có thể quên về SEO.

Cá nhân tôi khuyên bạn không nên làm điều này vì có quá nhiều rủi ro.

Không sử dụng WS để phục vụ các trang web, hãy sử dụng nó để phục vụ các ứng dụng web

Tuy nhiên, nếu bạn có một món đồ chơi hoặc một trang web cá nhân, hãy sử dụng nó. Hãy thử nó, tiên tiến. Đối với một doanh nghiệp hoặc công ty, bạn không thể biện minh cho rủi ro khi làm điều này.


7

Tôi đã học được một bài học nhỏ (con đường khó khăn). Tôi đã tạo một ứng dụng xử lý số chạy trên dịch vụ đám mây Ubuntu AWS EC2 (sử dụng GPU mạnh mẽ) và tôi muốn tạo một giao diện người dùng chỉ để xem tiến trình của nó trong thời gian thực. Do thực tế là nó cần dữ liệu thời gian thực, rõ ràng là tôi cần websockets để đẩy các bản cập nhật.

Nó bắt đầu với một bằng chứng về khái niệm, và hoạt động tuyệt vời. Nhưng sau đó khi chúng tôi muốn cung cấp cho công chúng, chúng tôi phải thêm phiên người dùng, vì vậy chúng tôi cần các tính năng đăng nhập. Và bất kể bạn nhìn vào nó như thế nào, websocket phải biết nó giao dịch với người dùng nào, vì vậy chúng tôi đã sử dụng cách sử dụng websockets để xác thực người dùng . Nó có vẻ hiển nhiên, và nó thật tiện lợi.

Chúng tôi thực sự đã phải dành một khoảng thời gian yên tĩnh để làm cho các kết nối đáng tin cậy. Chúng tôi đã bắt đầu với một số hướng dẫn websocket giá rẻ, nhưng phát hiện ra rằng việc triển khai của chúng tôi không thể tự động kết nối lại khi kết nối bị hỏng. Tất cả đều được cải thiện khi chúng tôi chuyển sang socket-io. Socket-io là phải!

Thành thật mà nói, tôi nghĩ rằng chúng ta đã bỏ lỡ một số tính năng tuyệt vời của socket-io. Socket-io có rất nhiều thứ để cung cấp và tôi chắc chắn rằng, nếu bạn tính đến nó trong thiết kế ban đầu của mình, bạn có thể tận dụng được nhiều hơn thế. Ngược lại, chúng tôi chỉ thay thế các websockets cũ bằng chức năng websocket của socket-io, và chỉ có vậy. (không có phòng, không có kênh, ...) Một thiết kế lại có thể làm cho mọi thứ trở nên mạnh mẽ hơn. Nhưng chúng tôi không có thời gian cho việc đó. Đó là điều cần ghi nhớ cho dự án tiếp theo của chúng tôi.

Tiếp theo, chúng tôi bắt đầu lưu trữ ngày càng nhiều dữ liệu (lịch sử người dùng, hóa đơn, giao dịch, ...). Chúng tôi đã lưu trữ tất cả trong cơ sở dữ liệu AWS dynamicodb và LẠI, chúng tôi đã sử dụng socket-io để giao tiếp các hoạt động CRUD từ front-end tới backend. Tôi nghĩ rằng chúng tôi đã rẽ sai ở đó. Đó là một sai lầm.

  • Bởi vì ngay sau khi chúng tôi phát hiện ra rằng các dịch vụ đám mây của Amazon (AWS) cung cấp một số công cụ cân bằng tải / mở rộng quy mô tuyệt vời cho các ứng dụng RESTful .
  • Bây giờ chúng tôi có ấn tượng rằng chúng tôi cần phải viết rất nhiều mã để thực hiện bắt tay các thao tác của CRUD.
  • Gần đây, chúng tôi đã triển khai tích hợp Paypal. Chúng tôi đã quản lý để làm cho nó hoạt động. Nhưng một lần nữa, tất cả các hướng dẫn đều làm điều đó với các API RESTful . Chúng tôi đã phải viết lại / suy nghĩ lại các ví dụ của họ để triển khai chúng với websockets. Mặc dù vậy, chúng tôi đã làm cho nó hoạt động khá nhanh. Nhưng có cảm giác như chúng ta đang đi ngược lại dòng chảy.

Đã nói tất cả những điều đó, chúng tôi sẽ phát trực tiếp vào tuần tới. Chúng tôi đến đó đúng lúc, mọi thứ đều hoạt động. Và nó nhanh, nhưng nó sẽ mở rộng?


Chỉ tự hỏi khi chúng tôi đang cố gắng tự đưa ra quyết định này, liệu nó có mở rộng quy mô tốt với AWS không?
Gabe

1
@Gabe rõ ràng là nút có thể dễ dàng lấy 100 kết nối socket-io trên một phiên bản aws giá rẻ. Chúng tôi chưa nhận thấy bất kỳ vấn đề hiệu suất nào. Tuy nhiên, một trong những hiệu ứng kỳ lạ là những người truy cập trang web của bạn một lần, nhưng sau đó để trang web mở trong một tab, tiếp tục sử dụng các kết nối. (và điều đó xảy ra thường xuyên trên điện thoại di động). Vì vậy, bạn cần ít nhất một loại cơ chế để loại bỏ những người dùng nhàn rỗi. Mặc dù vậy, tôi vẫn chưa nỗ lực để làm điều đó, vì màn trình diễn của chúng tôi không bị ảnh hưởng bởi điều đó. - Vì vậy, không cần scalling được nêu ra.
bvdb

4

Tôi sẽ xem xét sử dụng cả hai . Mỗi công nghệ đều có giá trị riêng và không có giải pháp chung nào phù hợp với tất cả.

Việc tách rời công việc diễn ra theo hướng này:

  1. WebSockets sẽ là phương thức chính của một ứng dụng để giao tiếp với máy chủ khi một phiên được yêu cầu. Điều này giúp loại bỏ nhiều hack cần thiết cho các trình duyệt cũ hơn (vấn đề là hỗ trợ cho các trình duyệt cũ hơn sẽ loại bỏ điều này)

  2. API RESTful được sử dụng cho các lệnh gọi GET không theo hướng phiên (tức là không cần xác thực) được hưởng lợi từ bộ nhớ đệm của trình duyệt. Một ví dụ điển hình về điều này sẽ là dữ liệu tham chiếu cho trình đơn thả xuống được sử dụng bởi một ứng dụng web. Tuy nhiên. có thể thay đổi thường xuyên hơn một chút so với ...

  3. HTML và Javascript. Chúng bao gồm giao diện người dùng của ứng dụng web. Những điều này nói chung sẽ có lợi khi được đặt trên CDN.

  4. Dịch vụ Web sử dụng WSDL vẫn là cách tốt nhất ở cấp độ doanh nghiệp và giao tiếp giữa các doanh nghiệp vì nó cung cấp một tiêu chuẩn được xác định rõ ràng cho việc truyền thông điệp và dữ liệu. Trước hết, bạn phải tải nó xuống thiết bị Datapower để ủy quyền cho trình xử lý dịch vụ web của bạn.

Tất cả điều này xảy ra trên giao thức HTTP đã cho phép sử dụng các ổ cắm an toàn thông qua SSL.

Tuy nhiên, đối với ứng dụng di động, websockets không thể kết nối lại với một phiên bị ngắt kết nối ( Cách kết nối lại với websocket sau khi kết nối đóng ) và việc quản lý điều đó không hề đơn giản. Vì vậy, đối với các ứng dụng dành cho thiết bị di động , tôi vẫn khuyên bạn nên sử dụng API REST và thăm dò ý kiến.

Một điều khác cần chú ý khi sử dụng WebSockets vs REST là khả năng mở rộng . Các phiên WebSocket vẫn được quản lý bởi máy chủ. RESTful API khi được thực hiện đúng cách sẽ không có trạng thái (có nghĩa là không có trạng thái máy chủ cần được quản lý), do đó khả năng mở rộng có thể phát triển theo chiều ngang (rẻ hơn) so với chiều dọc .


2

Tôi có muốn cập nhật từ máy chủ không?

  • Có: Socket.io
  • Không: REST

Nhược điểm của Socket.io là:

  • Khả năng mở rộng: WebSockets yêu cầu các kết nối mở và thiết lập Ops khác nhiều so với quy mô web.
  • Learnin: Tôi không có thời gian vô hạn cho việc học của mình. Mọi thứ phải hoàn thành!

Tôi sẽ vẫn sử dụng Socket.io trong dự án của mình, nhưng không sử dụng cho các biểu mẫu web cơ bản mà REST sẽ làm tốt.


1

Việc vận chuyển dựa trên WebSockets (hoặc thăm dò dài) chủ yếu phục vụ cho giao tiếp (gần) thời gian thực giữa máy chủ và máy khách. Mặc dù có rất nhiều trường hợp yêu cầu các loại phương tiện này, chẳng hạn như trò chuyện hoặc một số loại nguồn cấp dữ liệu thời gian thực hoặc các nội dung khác, nhưng không phải tất cả các phần của một số ứng dụng web cần phải được kết nối hai chiều với máy chủ.

REST là kiến ​​trúc dựa trên tài nguyên được hiểu rõ và mang lại những lợi ích riêng so với các kiến ​​trúc khác. WebSockets nghiêng nhiều hơn đến các luồng / nguồn cấp dữ liệu trong thời gian thực, điều này sẽ yêu cầu bạn tạo một số loại logic dựa trên máy chủ để ưu tiên hoặc phân biệt giữa tài nguyên và nguồn cấp dữ liệu (trong trường hợp bạn không muốn sử dụng REST).

Tôi giả định rằng cuối cùng sẽ có nhiều khuôn khổ trung tâm của WebSockets như socketstream trong tương lai khi quá trình truyền tải này sẽ phổ biến hơn và được hiểu rõ hơn / được lập thành văn bản dưới dạng phân phối kiểu dữ liệu / dạng bất khả tri. Tuy nhiên, tôi nghĩ, điều này không có nghĩa là nó sẽ / nên thay thế REST chỉ vì nó cung cấp chức năng không nhất thiết phải có trong nhiều trường hợp và tình huống sử dụng.


-1

Đó không phải là một ý tưởng hay. Tiêu chuẩn thậm chí còn chưa được hoàn thiện, hỗ trợ khác nhau giữa các trình duyệt, v.v. Nếu bạn muốn làm điều này ngay bây giờ, bạn sẽ cần phải dự phòng để flash hoặc thăm dò dài, v.v. Trong tương lai, nó có thể vẫn sẽ không tạo ra rất có ý nghĩa, vì máy chủ phải hỗ trợ mở các kết nối cho mọi người dùng. Thay vào đó, hầu hết các máy chủ web được thiết kế để vượt trội trong việc phản hồi nhanh các yêu cầu và đóng chúng nhanh nhất có thể. Thậm chí, hệ điều hành của bạn sẽ phải được điều chỉnh để đối phó với số lượng kết nối đồng thời cao (mỗi kết nối sử dụng nhiều cổng và bộ nhớ tạm thời hơn). Sử dụng REST cho nhiều trang web nhất có thể.


Có hầu hết các trang web vượt trội ở HTTP. Nhưng node.js không phải là một máy chủ web, nó là một thư viện io. Nó có thể làm TCP tốt. Câu hỏi về cơ bản là chúng ta có thể thiết kế trang web để sử dụng TCP thay vì HTTP hay không.
Raynos

Các hạn chế tương tự cũng được áp dụng, bạn vẫn sẽ hết các cổng / bộ nhớ tạm thời, nó vẫn sẽ giới hạn số người bạn có thể phục vụ đồng thời và tạo gánh nặng không cần thiết cho hệ thống.
zeekay

vâng, có một giới hạn nhưng tôi không nghĩ đó là vấn đề lớn nếu bạn không tạo một chuỗi mới cho mỗi kết nối.
Raynos

Tôi đã có một ổ cắm cho mọi người dùng. trò chuyện toàn cầu + nguồn cấp tin tức.
Harry

1
Tôi đoán vào năm 2011, đây là một nhà cảm xạ tuyệt vời. - Vậy, tôi xem bạn đến từ đâu. Nhưng vào năm 2019, websockets đã hoàn thiện.
bvdb
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.