Sự khác nhau giữa socket.io và websockets


459

Sự khác biệt giữa socket.io và websockets trong node.js là gì?
Có phải cả hai công nghệ đẩy máy chủ? Sự khác biệt duy nhất tôi cảm thấy là,

  1. socket.io cho phép tôi gửi / phát tin nhắn bằng cách chỉ định tên sự kiện.

  2. Trong trường hợp socket.io, một tin nhắn từ máy chủ sẽ đến tất cả các máy khách, nhưng với cùng một websockets, tôi buộc phải giữ một mảng của tất cả các kết nối và lặp qua nó để gửi tin nhắn cho tất cả các máy khách.

Ngoài ra, tôi tự hỏi tại sao các thanh tra web (như Chrome / fireorms / fiddler) không thể bắt được những tin nhắn này (từ socket.io/websocket) từ máy chủ?

Hãy làm rõ điều này.


6
Về lý do tại sao các thanh tra web không bắt được lưu lượng truy cập: xem Làm thế nào để xem nội dung yêu cầu Websocket của WS / WSS bằng cách sử dụng Fireorms hoặc khác?
treaz

1
@treaz bạn không cần Firebird hay bất cứ thứ gì khác. Các devtools của Chrome hiển thị các kết nối WS trong tab mạng.

Kiểm tra điều này quá (không chắc đây có phải là mới nhất không) - learnba.com/websocket-vs-socket-io
Manohar Reddy Poreddy 24/11/19

Câu trả lời:


326

Ưu điểm của nó là đơn giản hóa việc sử dụng WebSockets như bạn đã mô tả trong # 2 và quan trọng hơn là nó cung cấp dự phòng cho các giao thức khác trong trường hợp WebSockets không được hỗ trợ trên trình duyệt hoặc máy chủ. Tôi sẽ tránh sử dụng WebSockets trực tiếp trừ khi bạn rất quen thuộc với môi trường nào chúng không hoạt động và bạn có khả năng giải quyết những hạn chế đó.

Đây là một bài đọc tốt trên cả WebSockets và Socket.IO.

http://davidwalsh.name/websocket


63
Socket.IO không được xây dựng trên WebSockets, nó chỉ sử dụng công nghệ này khi có sẵn.
moka

24
Sự khác biệt về ngữ nghĩa và tôi đã giải thích rằng trong phần còn lại của câu trả lời, nhưng tôi đã cập nhật câu trả lời để phản ánh điều này.
Timothy Strimple

1
@moka, từ lời của bạn tôi có thể kết luận rằng tuyên bố sau là sai? Socket.IO thực sự là nhiều hơn một lớp trên WebSockets.
Pulak Kanti Bhattacharyya

3
@PulakKantiBhattacharyya bạn có thể vui lòng chỉ định chính xác câu nói nào bạn đang đề cập đến không? Socket.IO không chỉ là một lớp trên WebSockets, nó có ngữ nghĩa khác nhau (đánh dấu các thông điệp có tên) và không chuyển sang các giao thức khác nhau, cũng có cơ chế nhịp tim. Thêm vào đó là gắn ID cho khách hàng ở phía máy chủ và hơn thế nữa. Vì vậy, nó không chỉ là một trình bao bọc, nó là thư viện đầy đủ tính năng. Trên thực tế, nó đã không được hỗ trợ tốt trong những năm gần đây, vì vậy tôi khuyên bạn nên sử dụng SockJS, cách tốt hơn và được duy trì thay thế cho Socket.IO.
moka

4
@moka Một tháng trước tôi đã đồng ý với bạn. Hiện tại, socket.io 1.0 đã ra mắt và đang được cập nhật.
Timothy Strimple

537

Quan niệm sai lầm

Có một vài hiểu lầm phổ biến liên quan đến WebSocket và Socket.IO:

  1. Quan niệm sai lầm đầu tiên là việc sử dụng Socket.IO dễ dàng hơn đáng kể so với sử dụng WebSocket dường như không phải là trường hợp. Xem ví dụ dưới đây.

  2. Quan niệm sai lầm thứ hai là WebSocket không được hỗ trợ rộng rãi trong các trình duyệt. Xem bên dưới để biết thêm.

  3. Quan niệm sai lầm thứ ba là Socket.IO hạ cấp kết nối dưới dạng dự phòng trên các trình duyệt cũ hơn. Nó thực sự giả định rằng trình duyệt đã cũ và bắt đầu kết nối AJAX với máy chủ, sau này được nâng cấp trên các trình duyệt hỗ trợ WebSocket, sau khi một số lưu lượng được trao đổi. Xem bên dưới để biết chi tiết.

Thí nghiệm của tôi

Tôi đã viết một mô-đun npm để chứng minh sự khác biệt giữa WebSocket và Socket.IO:

Đây là một ví dụ đơn giản về mã phía máy chủ và mã phía máy khách - máy khách kết nối với máy chủ bằng WebSocket hoặc Socket.IO và máy chủ gửi ba tin nhắn trong khoảng thời gian 1 giây, được máy khách thêm vào DOM.

Phía máy chủ

So sánh ví dụ về phía máy chủ về việc sử dụng WebSocket và Socket.IO để làm điều tương tự trong ứng dụng Express.js:

Máy chủ WebSocket

Ví dụ máy chủ WebSocket sử dụng Express.js:

var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
  console.error('websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');

Nguồn: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

Máy chủ socket.IO

Ví dụ máy chủ Socket.IO sử dụng Express.js:

var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
  console.error('socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');

Nguồn: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Phía khách hàng

So sánh ví dụ về phía khách hàng về việc sử dụng WebSocket và Socket.IO để làm điều tương tự trong trình duyệt:

Máy khách WebSocket

Ví dụ ứng dụng khách WebSocket sử dụng JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });

Nguồn: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

Khách hàng của socket.IO

Ví dụ ứng dụng khách socket.IO sử dụng JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });

Nguồn: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

Lưu lượng truy cập mạng

Để thấy sự khác biệt trong lưu lượng mạng, bạn có thể chạy thử nghiệm của tôi . Đây là kết quả mà tôi nhận được:

Kết quả WebSocket

2 yêu cầu, 1,50 KB, 0,05 giây

Từ 2 yêu cầu đó:

  1. Trang HTML
  2. nâng cấp kết nối lên WebSocket

(Yêu cầu nâng cấp kết nối hiển thị trên các công cụ dành cho nhà phát triển với phản hồi 101 Giao thức chuyển đổi.)

Kết quả của socket.IO

6 yêu cầu, 181,56 KB, 0,25 giây

Từ 6 yêu cầu đó:

  1. chính trang HTML
  2. JavaScript của Socket.IO (180 kilobyte)
  3. yêu cầu AJAX bỏ phiếu dài đầu tiên
  4. yêu cầu AJAX bỏ phiếu dài thứ hai
  5. yêu cầu AJAX bỏ phiếu dài thứ ba
  6. nâng cấp kết nối lên WebSocket

Ảnh chụp màn hình

Kết quả WebSocket mà tôi nhận được trên localhost:

Kết quả WebSocket - mô đun websocket-vs-socket.io

Kết quả của Socket.IO mà tôi nhận được trên localhost:

Kết quả của Socket.IO - mô đun websocket-vs-socket.io

Tự kiểm tra

Bắt đầu nhanh:

# Install:
npm i -g websocket-vs-socket.io
# Run the server:
websocket-vs-socket.io

Mở http: // localhost: 3001 / trong trình duyệt của bạn, mở các công cụ dành cho nhà phát triển bằng Shift + Ctrl + I, mở tab Mạng và tải lại trang bằng Ctrl + R để xem lưu lượng truy cập mạng cho phiên bản WebSocket.

Mở http: // localhost: 3002 / trong trình duyệt của bạn, mở các công cụ dành cho nhà phát triển bằng Shift + Ctrl + I, mở tab Mạng và tải lại trang bằng Ctrl + R để xem lưu lượng truy cập mạng cho phiên bản Socket.IO.

Để gỡ cài đặt:

# Uninstall:
npm rm -g websocket-vs-socket.io

Tính tương thích của trình duyệt web

Kể từ tháng 6 năm 2016 WebSocket hoạt động trên mọi thứ trừ Opera Mini, bao gồm IE cao hơn 9.

Đây là khả năng tương thích trình duyệt của WebSocket trên Tôi có thể sử dụng kể từ tháng 6 năm 2016:

nhập mô tả hình ảnh ở đây

Xem http://caniuse.com/websockets để biết thông tin cập nhật.


23
Vì vậy, về cơ bản những gì bạn đang nói là, websocket tốt hơn socket.io?
Jack Moscovi

42
@JackMoscovi Tôi không nói rằng WebSocket nhất thiết phải tốt hơn. Tất cả phụ thuộc vào yêu cầu. Ưu điểm của WebSocket là nó là một tiêu chuẩn Web (đầu tiên là W3C và whatwg, bây giờ thuộc IETF, với RFC được xuất bản 5 năm trước), nó rất nhẹ bởi vì nó được hỗ trợ bởi các trình duyệt, nhưng hỗ trợ trình duyệt vẫn tốt không phổ quát. Socket.IO hỗ trợ nhiều trình duyệt hơn và có nhiều chức năng hơn, nhưng cũng đi kèm với một số chi phí. Đôi khi một cái tốt hơn, đôi khi cái kia. Giống như chọn giữa querySelectorAll và jQuery - câu trả lời không phải lúc nào cũng giống nhau
rsp

20
Câu trả lời tuyệt vời ở đây !! Dường như với tôi socket.io không còn cần thiết trong nhiều trường hợp ... Xem bài viết tuyệt vời này quá! Medium.com/@ivanderbyl/ Kẻ
Alvaro

4
@rsp Tôi không nghĩ rằng những ví dụ này là tương đương về chức năng? Socket-io xử lý những thứ như tự động kết nối lại khi bị gián đoạn (xảy ra trên thiết bị di động) và tôi nghĩ có những lo ngại về bảo mật xung quanh vấn đề nào được xử lý cho bạn? Các ví dụ WS đơn giản của bạn, trong khi tương đương về chức năng, không có các thuộc tính này.
mindplay.dk

28
So sánh rất tốt. Tuy nhiên, điều đáng chú ý là Socket.io thêm khoảng cách tên phòng, hàng tấn chi tiết kết nối, rất nhiều chi tiết đăng nhập và có rất nhiều thư viện tích hợp cho Socket.IO với Angular, Vue, React và các thứ khác. Quan trọng nhất, bạn có thể vô hiệu hóa việc bỏ phiếu dài Ajax và kết nối trực tiếp qua WebSocket giống như kết nối WebSocket thô. Bằng cách này, bạn có được mọi thứ trừ thư viện 180kb là bằng nhau. Sử dụng WebSocket trực tiếp là đau đớn trừ khi bạn chỉ cần mức tối thiểu. Bỏ phòng và truy cập vào IP cộng đồng là điều đáng ngại đối với doanh nghiệp.
Nick Steele

30

Tôi sẽ cung cấp một đối số chống lại việc sử dụng socket.io.

Tôi nghĩ rằng sử dụng socket.io chỉ vì nó có dự phòng không phải là một ý tưởng tốt. Hãy để IE8 RIP.

Trong quá khứ đã có nhiều trường hợp các phiên bản mới của NodeJS bị hỏng socket.io. Bạn có thể kiểm tra các danh sách này để biết ví dụ ... https://github.com/socketio/socket.io/issues?q=install+error

Nếu bạn định phát triển ứng dụng Android hoặc thứ gì đó cần để hoạt động với ứng dụng hiện tại của mình, có lẽ bạn sẽ ổn khi làm việc với WS ngay lập tức, socket.io có thể gây rắc rối cho bạn ở đó ...

Cộng với mô-đun WS cho Node.JS rất dễ sử dụng.


bạn đề nghị chúng tôi sử dụng gì để tương tác với mysql -> express.js / fastify.js hoặc node.js ... để xây dựng ứng dụng trò chuyện trên Android và ios
DragonFire

25

Sử dụng Socket.IO về cơ bản giống như sử dụng jQuery - bạn muốn hỗ trợ các trình duyệt cũ hơn, bạn cần viết ít mã hơn và thư viện sẽ cung cấp các dự phòng. Socket.io sử dụng công nghệ websockets nếu có, và nếu không, hãy kiểm tra loại giao tiếp tốt nhất hiện có và sử dụng nó.


3

Ngay cả khi các trình duyệt hiện đại hỗ trợ WebSockets ngay bây giờ, tôi nghĩ rằng không cần phải ném SocketIO đi và nó vẫn có chỗ đứng trong bất kỳ dự án hiện nay. Thật dễ hiểu và cá nhân tôi đã học được cách WebSockets hoạt động nhờ vào SocketIO.

Như đã nói trong chủ đề này, có rất nhiều thư viện tích hợp cho Angular, React, v.v. và các loại định nghĩa cho TypeScript và các ngôn ngữ lập trình khác.

Điểm khác tôi sẽ thêm vào sự khác biệt giữa Socket.io và WebSockets là việc phân cụm với Socket.io không phải là vấn đề lớn. Socket.io cung cấp Bộ điều hợp có thể được sử dụng để liên kết nó với Redis để tăng cường khả năng mở rộng. Bạn có ioredissocket.io-redis chẳng hạn.

Vâng tôi biết, SocketCluster tồn tại, nhưng đó là ngoài chủ đề.


2

Socket.IO sử dụng WebSocket và khi WebSocket không có sẵn, sử dụng thuật toán dự phòng để tạo kết nối thời gian thực.


0

https://socket.io/docs/#What-Socket-IO-is-not (với sự nhấn mạnh của tôi )

Những gì Socket.IO không phải là

Socket.IO KHÔNG phải là triển khai WebSocket. Mặc dù Socket.IO thực sự sử dụng WebSocket như một phương tiện vận chuyển khi có thể, nhưng nó bổ sung một số siêu dữ liệu cho mỗi gói: loại gói, không gian tên và id gói khi cần xác nhận thông báo. Đó là lý do tại sao máy khách WebSocket sẽ không thể kết nối thành công với máy chủ Socket.IOmáy khách Socket.IO cũng sẽ không thể kết nối với máy chủ WebSocket . Xin vui lòng xem các đặc điểm kỹ thuật giao thức ở đây .

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
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.