Hiệu suất có phải là lý do duy nhất để không sử dụng SignalR (websockets) hoàn toàn thay cho API REST truyền thống không?


42

Tôi đã sử dụng SignalRđể đạt được chức năng nhắn tin thời gian thực trong một số dự án của mình. Nó dường như hoạt động đáng tin cậy và rất dễ học để sử dụng.

Sự cám dỗ, ít nhất là đối với tôi, là từ bỏ việc phát triển dịch vụ API Web và sử dụng SignalRcho mọi thứ.

Tôi cảm thấy như điều này có thể đạt được bằng thiết kế chu đáo, và nếu có, điều đó có nghĩa là cần ít mã khách hàng hơn. Quan trọng hơn, điều đó có nghĩa là sẽ có một giao diện duy nhất cho các dịch vụ thay vì giao diện phân tách, và trong trường hợp xấu nhất, người ta có thể kết nối điều này mà không cần suy nghĩ khi nào mọi thứ được kết xuất, v.v.

Vì vậy, tôi muốn biết:

  1. Có bất kỳ lý do nào khác để không sử dụng SignalR thay cho tất cả các dịch vụ web bên cạnh hiệu suất không?
  2. Hiệu suất của SignalR có đủ liên quan đến việc nó sẽ không có ý nghĩa để làm như vậy không?

Từ lâu tôi đã mơ ước có thể dịch các định nghĩa đối tượng và dịch vụ phía máy chủ sang mã truy cập dịch vụ phía máy khách mà không cần một cái gì đó ngớ ngẩn như thế node.js. Chẳng hạn, nếu tôi xác định một đối tượng thú vị InterestingObjectvà một dịch vụ cho CRUDđối tượng đó InterestingObjectService, tôi có thể xác định một tuyến URL tiêu chuẩn đến dịch vụ - giả sử, "/ {serviceName} / {methodName}" - nhưng tôi vẫn cần viết mã máy khách để truy cập dịch vụ. Vì đối tượng sẽ được truyền từ máy khách đến máy chủ và quay lại, không có lý do thực tế nào để để xác định rõ ràng đối tượng trong mã phía máy khách, cũng không cần phải xác định rõ ràng các tuyến đường để thực hiện các hoạt động CRUD. Tôi cảm thấy nên có một cách để chuẩn hóa tất cả những điều này để có thể viết một ứng dụng khách theo giả định rằng truy cập dịch vụ hoạt động từ máy khách đến máy chủ và trở lại trong suốt như khi tôi viết WinForms hoặc Java Applet hoặc ứng dụng gốc hoặc những gì có bạn.

Nếu SignalR đủ tốt để sử dụng thay cho dịch vụ web truyền thống, thì đó có thể là một cách khả thi để đạt được điều này. SignalR đã bao gồm chức năng để làm cho trung tâm hoạt động giống như dịch vụ mà tôi mô tả, vì vậy tôi có thể xác định dịch vụ cơ sở chung (CRUD) sẽ cung cấp tất cả các chức năng này bên ngoài với một số phản ánh. Sau đó, tôi gần như có thể được cấp quyền truy cập dịch vụ, tiết kiệm cho tôi sự khó chịu khi viết lại mã để truy cập vào thứ gì đó có thể được truy cập theo quy ước - và quan trọng hơn, tôi sẽ phải dành thời gian viết mã để xác định cách cập nhật mã này DOM.

Sau khi đọc bản chỉnh sửa của tôi, tôi cảm thấy nó có thể hơi vô lý vì vậy xin vui lòng hỏi tôi nếu bạn có thắc mắc về những gì tôi đang nhận được. Về cơ bản, tôi muốn quyền truy cập dịch vụ càng minh bạch càng tốt.


5
Nếu bạn có một card mạng ma thuật có thể mở vô số ổ cắm và một mạng ma thuật có thể hỗ trợ một lượng băng thông vô hạn và một máy chủ ma thuật có số lượng bộ nhớ và chu kỳ cpu vô hạn thì websockets chỉ là một lựa chọn tuyệt vời!

Csla làm những gì bạn muốn, các đối tượng kinh doanh có thể tự di chuyển giữa máy khách và máy chủ.
Andy

Câu trả lời:


50

Hai công nghệ đó có một mục đích rất khác nhau.

  • REST dành cho các cuộc gọi thông thường đến API, với ứng dụng khách là tác nhân tích cực của trao đổi. Khi khách hàng cần tìm tọa độ GPS của một địa chỉ, khách hàng sẽ thực hiện cuộc gọi đến API và đợi cho đến khi nhận được tọa độ, hoặc xảy ra lỗi hoặc hết thời gian chờ.

  • Web socket là cho tất cả mọi thứ cần phải làm mọi thứ theo cách ngược lại. Ví dụ: khi tôi sử dụng trang web mạng nội bộ hiển thị cho tôi nhật ký thời gian thực và hiệu suất của các máy chủ khác nhau, máy khách có thể bị động và đợi cho đến khi máy chủ gửi cho anh ta thông báo nhật ký mới được công bố hoặc số liệu hiệu suất.

Sự khác biệt là rõ ràng: trong trường hợp đầu tiên, khách hàng quyết định khi nào cần một thông tin cụ thể; trong trường hợp thứ hai, khách hàng chỉ cần chờ để được liên lạc và có thể không biết khi nào sẽ có.

Theo một cách nào đó, cả hai đều có thể hoán đổi cho nhau: bạn có thể triển khai các socket web khi bạn không cần chúng (tức là máy khách sẽ gọi máy chủ thông qua socket web thay vì thực hiện cuộc gọi REST) ​​và bạn có thể sử dụng bỏ phiếu hoặc bỏ phiếu dài để thay thế ổ cắm web (cho rằng điều này đã được sử dụng thành công trong nhiều năm cho đến khi ổ cắm web trở nên phổ biến).

Nhưng khả năng thay thế lẫn nhau của họ phải trả giá:

  • Khi bạn sử dụng bỏ phiếu hoặc bỏ phiếu dài thay vì ổ cắm web, bạn thường lãng phí băng thông.

  • Khi bạn sử dụng ổ cắm web để thực hiện những gì có thể được thực hiện thông qua api web, bạn sẽ giữ tất cả các kết nối từ tất cả các máy khách đang hoạt động, đây có thể không phải là điều bạn thực sự muốn. Đối với một trang web nhỏ nơi bạn mong muốn có tối đa 5 khách hàng cùng một lúc, đây không phải là vấn đề. Đối với một dịch vụ như Amazon AWS, điều này sẽ không dễ giải quyết về mặt kỹ thuật.

Đừng sử dụng ổ cắm web khi bạn không cần chúng. Để có tọa độ GPS của một địa chỉ, tôi không nhận được gì khi mở kết nối ổ cắm web, thực hiện cuộc gọi, chờ câu trả lời và đóng kết nối: REST đáp ứng nhu cầu của tôi cho các tình huống như vậy.

  • Nếu bạn thấy mình lặp đi lặp lại và thường xuyên kiểm tra thông tin thông qua cuộc gọi REST đến dịch vụ, đây có thể là một dấu hiệu tốt cho thấy bạn nên chuyển sang ổ cắm web. Tương tự, Stack Overflow giảm mức sử dụng băng thông bằng cách sử dụng các ổ cắm web, vì nó giúp mọi người không mất thời gian nhấn F5 trên trang chủ để xem họ có tin nhắn mới hay không.

  • Nếu bạn thấy rằng bạn mở các kết nối ổ cắm web, hãy sử dụng chúng để thực hiện một cuộc gọi và sau đó đóng chúng hoặc nếu kết nối của bạn vẫn mở nhưng máy chủ chỉ gửi một cái gì đó cho khách hàng theo yêu cầu của khách hàng, hãy chuyển sang REST.

Ngoài ra, các socket web vẫn có một hỗ trợ hạn chế và không phải lúc nào cũng dễ thực hiện. Mặc dù SignalR giúp dễ dàng thực hiện, nhưng điều này không có nghĩa là bạn sẽ không gặp khó khăn gì khi triển khai nó trong các ngôn ngữ / bối cảnh / môi trường khác. Với REST, điều đó thật dễ dàng: đó có thể là một curlcuộc gọi hoặc một tính năng tương tự có sẵn trong mọi ngôn ngữ chính. Với các ổ cắm web, bạn không thể chắc chắn sẽ mất bao lâu để tạo một ứng dụng khách bằng cách sử dụng [chèn tên ngôn ngữ mà bạn chưa biết ở đây].

Tôi đã sử dụng ổ cắm web trong một số dự án trong .NET, Python và node.js.

  • Trong .NET, điều đó không quá khó, nhưng vẫn vậy, tôi vẫn dành vài ngày để cố gắng tìm ra một số vấn đề về mật mã, chẳng hạn như kết nối bị rớt ngay khi mở. (Điều này là trước SignalR; Tôi chưa bao giờ thử SignalR). Tôi cũng đã sử dụng WCF trong chế độ ổ cắm web, điều này cũng không có vấn đề gì (nhưng tôi tin rằng WCF luôn đi kèm với các vấn đề).

  • Trong node.js, điều này là có thể thực hiện được, nhưng tôi đã phải chuyển đổi hai lần các thư viện cho đến khi tôi tìm thấy một thư viện hoạt động. Tôi tin rằng tôi đã dành ít nhất một tuần để cố gắng tạo ra một ổ cắm web Hello World.

  • Trong Python, tôi đã thử một lần, dành hai hoặc ba ngày và bỏ rơi. Nó không bao giờ làm việc.

So sánh điều này với REST: vấn đề duy nhất người ta có thể gặp phải với một ngôn ngữ / khung mới là biết cách POST các tệp hoặc nhận được phản hồi nhị phân rất lớn. Tôi nhớ đã dành một vài giờ để tìm kiếm giải pháp cho một số ngôn ngữ. Tuy nhiên, một vài giờ cho một trường hợp đặc biệt không là gì so với ngày hoặc tuần đối với một Hello World đơn giản.


2
Đánh giá cao câu trả lời của bạn, MainMa, vì tôi thấy nó thú vị / hữu ích. Có một điểm tôi không hiểu mặc dù. Bạn đề cập rằng một số lượng nhỏ khách hàng có thể xử lý các ổ cắm web (ví dụ: nhiều nhất là 5 cùng một lúc). Sau đó, bạn đề cập StackOverflow sử dụng ổ cắm web trên trang chủ của họ. Làm thế nào để họ xử lý một số lượng lớn người dùng như vậy? Tôi hỏi bởi vì tôi đang thử hơn 20 kết nối SignalR và tôi thấy sự chậm trễ của tin nhắn bắt đầu chậm lại, trước khi toàn bộ sự việc xảy ra (mọi thứ không phản hồi).
gnychis

1
@gnychis: có nhiều giải pháp cho điều đó, nhưng nhiều giải pháp trong số đó liên quan nhiều hơn đến chính cơ sở hạ tầng (đó là những gì serverfault.com dành cho). Nói chung, ném nhiều phần cứng và phân chia người dùng giữa các tên miền, để một số kết nối được xử lý bởi sockets1.example.com, một số khác bởi sockets2.example.com, v.v ... Khá hiệu quả nhưng cũng khá tốn kém về phần cứng và băng thông.
Arseni Mourzenko

3
Câu trả lời này là tuyệt vời, nhưng tôi muốn thu hẹp câu hỏi ban đầu. Nếu một ứng dụng yêu cầu kết nối websocket liên tục, thì tại sao không sử dụng hoàn toàn websockets thay cho API REST? Vì một websocket được mở, có lẽ nó nên được sử dụng đầy đủ.
HappyNomad

Tôi chỉ tìm thấy một câu trả lời cho câu hỏi của riêng tôi.
HappyNomad

1

Chỉ 2 xu của tôi ...

Tôi nghĩ rằng nó không thực sự về hiệu suất hoặc bất cứ điều gì. Đó là về tiêu chuẩn. REST là một tiêu chuẩn và IMHO có những ưu điểm sau:

  • Yêu cầu HTTP rất đơn giản để sử dụng. Mọi người đều có thể nhanh chóng sử dụng API REST. Heck, bạn thậm chí có thể mở trình duyệt và nhập URL để xem dữ liệu, bạn có thể tương tác nhiều hơn như thế nào?
  • (Hầu như) bất kỳ ngôn ngữ lập trình đều có thể sử dụng nó. Đó là một loại giao diện phổ quát. Giao diện với SignalR từ một ngôn ngữ kỳ lạ dường như ít rõ ràng hơn.
  • Nó có hỗ trợ công cụ tốt, như http://petstore.swagger.wordnik.com/
  • Đó là một "giao diện" đẹp để gỡ lỗi. Bạn có thể dễ dàng theo dõi tin nhắn đến và đi trực tiếp trong trình duyệt, xem dữ liệu, v.v ... Với websockets và thư viện tùy chỉnh, không rõ ràng, bạn phải ghi nhật ký mọi thứ một cách rõ ràng.

1
Mặc dù bạn đưa ra một số điểm tốt về API REST đơn giản hơn một chút và có thể có công cụ tốt hơn, câu trả lời này nói lên một số điều không đúng. REST không phải là một tiêu chuẩn , trong khi WebSockets là .
StriplingWar Warrior

1
Tôi đoán đó là từ ngữ kém từ phần của tôi. Ý tôi là với "tiêu chuẩn" là phổ biến, được sử dụng rộng rãi, cách làm việc mặc định ... và không "là một Tiêu chuẩn RFC".
dagnelies

Làm rõ tốt. Và, btw, Chrome ít nhất cho phép bạn xem lưu lượng truy cập WebSockets trong các công cụ dev của nó. Tôi tưởng tượng các trình duyệt khác có thể làm quá.
StriplingWar Warrior
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.