ความแตกต่างระหว่าง socket.io และ websockets


459

ความแตกต่างระหว่าง socket.io และ websockets ใน node.js คืออะไร?
พวกเขาทั้งสองเทคโนโลยีผลักเซิร์ฟเวอร์? ความแตกต่างเพียงอย่างเดียวที่ฉันรู้สึกคือ

  1. socket.io อนุญาตให้ฉันส่ง / ส่งข้อความโดยระบุชื่อเหตุการณ์

  2. ในกรณีของ socket.io ข้อความจากเซิร์ฟเวอร์จะเข้าถึงลูกค้าทั้งหมด แต่สำหรับ websockets เดียวกันฉันถูกบังคับให้เก็บอาร์เรย์ของการเชื่อมต่อทั้งหมดและวนผ่านมันเพื่อส่งข้อความไปยังลูกค้าทั้งหมด

นอกจากนี้ฉันสงสัยว่าทำไมผู้ตรวจสอบเว็บไซต์ (เช่น Chrome / firebug / fiddler) ไม่สามารถจับข้อความเหล่านี้ (จาก socket.io/websocket) จากเซิร์ฟเวอร์ได้หรือไม่

โปรดอธิบายสิ่งนี้


6
เกี่ยวกับสาเหตุที่ผู้ตรวจสอบเว็บไม่จับปริมาณการใช้งาน: ดูวิธีดูเนื้อหาคำขอ WS / WSS Websocket โดยใช้ Firebug หรืออื่น ๆ
treaz

1
@treaz คุณไม่จำเป็นต้องใช้ Firebug หรืออย่างอื่น devtools ของ Chrome แสดงการเชื่อมต่อ WS ภายใต้แท็บเครือข่าย

ตรวจสอบเรื่องนี้ด้วย (ไม่แน่ใจว่านี่เป็นรุ่นล่าสุดหรือไม่) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

คำตอบ:


326

ข้อดีของมันคือทำให้การใช้งาน WebSockets ง่ายขึ้นตามที่คุณอธิบายไว้ใน # 2 และที่สำคัญกว่านั้นคือมันไม่สามารถทำงานได้กับโปรโตคอลอื่น ๆ ในกรณีที่ไม่รองรับ WebSockets บนเบราว์เซอร์หรือเซิร์ฟเวอร์ ฉันจะหลีกเลี่ยงการใช้ WebSockets โดยตรงเว้นแต่คุณจะคุ้นเคยกับสภาพแวดล้อมที่ไม่สามารถใช้งานได้และคุณสามารถแก้ไขข้อ จำกัด เหล่านั้นได้

นี่เป็นการอ่านที่ดีทั้งบน WebSockets และ Socket.IO

http://davidwalsh.name/websocket


63
Socket.IO ไม่ได้สร้างบน WebSockets แต่จะใช้เทคโนโลยีนี้เมื่อพร้อมใช้งาน
moka

24
ความแตกต่างทางความหมายและฉันอธิบายว่าในคำตอบที่เหลือ แต่ฉันได้อัปเดตคำตอบเพื่อสะท้อนสิ่งนี้
Timothy Strimple

1
@moka จากคำพูดของคุณฉันสามารถสรุปได้ว่าข้อความต่อไปนี้ผิดหรือเปล่า? Socket.IO เป็นจริงมากกว่าเลเยอร์บน WebSockets
Pulak Kanti Bhattacharyya

3
@PulakKantiBhattacharyya คุณช่วยกรุณาระบุคำสั่งที่คุณอ้างถึงอย่างแน่นอน? Socket.IO เป็นมากกว่าเลเยอร์เหนือ WebSockets แต่มีซีแมนทิกส์ต่าง ๆ (ทำเครื่องหมายข้อความด้วยชื่อ) และไม่ทำโพรโทคอลที่แตกต่างกันรวมถึงกลไกการเต้นของหัวใจ เพิ่มเติมที่แนบ ID ของลูกค้าฝั่งเซิร์ฟเวอร์และอื่น ๆ ดังนั้นมันจึงไม่ใช่แค่เสื้อคลุมเท่านั้น แต่เป็นห้องสมุดเต็มรูปแบบ ในความเป็นจริงมันไม่ได้รับการสนับสนุนเป็นอย่างดีในช่วงไม่กี่ปีที่ผ่านมาดังนั้นฉันขอแนะนำให้ใช้ SockJS ซึ่งเป็นทางเลือกที่ดีกว่าและคงไว้ซึ่ง Socket.IO
moka

4
@moka เดือนที่แล้วฉันจะเห็นด้วยกับคุณ Socket.io 1.0 ออกมาแล้วและกำลังรับการอัพเดท
Timothy Strimple

536

ความเข้าใจผิด

มีความเข้าใจผิดบางประการเกี่ยวกับ WebSocket และ Socket.IO:

  1. ความเข้าใจผิดครั้งแรกคือการใช้ Socket.IO ง่ายกว่าการใช้ WebSocket ซึ่งดูเหมือนจะไม่เป็นเช่นนั้น ดูตัวอย่างด้านล่าง

  2. ความเข้าใจผิดที่สองคือ WebSocket ไม่ได้รับการสนับสนุนอย่างกว้างขวางในเบราว์เซอร์ ดูด้านล่างสำหรับข้อมูลเพิ่มเติม

  3. ความเข้าใจผิดที่สามคือ Socket.IO ปรับลดการเชื่อมต่อเป็นทางเลือกในเบราว์เซอร์รุ่นเก่า จริง ๆ แล้วมันสันนิษฐานว่าเบราว์เซอร์เก่าและเริ่มการเชื่อมต่อ AJAX ไปยังเซิร์ฟเวอร์ที่ได้รับการอัพเกรดในภายหลังบนเบราว์เซอร์ที่รองรับ WebSocket หลังจากมีการแลกเปลี่ยนปริมาณการใช้งาน ดูรายละเอียดด้านล่าง

การทดลองของฉัน

ฉันเขียนโมดูล npm เพื่อสาธิตความแตกต่างระหว่าง WebSocket และ Socket.IO:

มันเป็นตัวอย่างง่าย ๆ ของฝั่งเซิร์ฟเวอร์และรหัสฝั่งไคลเอ็นต์ - ไคลเอ็นต์เชื่อมต่อกับเซิร์ฟเวอร์โดยใช้ WebSocket หรือ Socket.IO และเซิร์ฟเวอร์ส่งข้อความสามข้อความในช่วงเวลา 1s ซึ่งถูกเพิ่มไปยัง DOM โดยไคลเอนต์

ฝั่งเซิร์ฟเวอร์

เปรียบเทียบตัวอย่างฝั่งเซิร์ฟเวอร์ของการใช้ WebSocket และ Socket.IO เพื่อทำสิ่งเดียวกันในแอป Express.js:

WebSocket เซิร์ฟเวอร์

ตัวอย่างเซิร์ฟเวอร์ WebSocket โดยใช้ 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');

ที่มา: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

เซิร์ฟเวอร์ Socket.IO

ตัวอย่างเซิร์ฟเวอร์ Socket.IO โดยใช้ 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');

ที่มา: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

ด้านลูกค้า

เปรียบเทียบตัวอย่างฝั่งไคลเอ็นต์ของการใช้ WebSocket และ Socket.IO เพื่อทำสิ่งเดียวกันในเบราว์เซอร์:

WebSocket ไคลเอนต์

ตัวอย่างไคลเอ็นต์ WebSocket โดยใช้ JavaScript วานิลลา:

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); });

ที่มา: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

ลูกค้า Socket.IO

ตัวอย่างไคลเอ็นต์ Socket.IO ใช้ vanilla JavaScript:

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); });

ที่มา: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

การรับส่งข้อมูลเครือข่าย

หากต้องการดูความแตกต่างของปริมาณการใช้เครือข่ายคุณสามารถเรียกใช้การทดสอบของฉันได้ นี่คือผลลัพธ์ที่ฉันได้รับ:

ผลลัพธ์ WebSocket

2 คำขอ, 1.50 KB, 0.05 วิ

จากคำขอ 2 ข้อดังกล่าว:

  1. หน้า HTML เอง
  2. อัพเกรดการเชื่อมต่อเป็น WebSocket

(คำขออัพเกรดการเชื่อมต่อสามารถมองเห็นได้บนเครื่องมือสำหรับนักพัฒนาที่มีการตอบสนองการเปลี่ยนโปรโตคอล 101)

ผลลัพธ์ Socket.IO

6 คำขอ 181.56 KB, 0.25 วิ

จากคำขอทั้ง 6 ข้อนั้น:

  1. หน้า HTML เอง
  2. จาวาสคริปต์ของ Socket.IO (180 กิโลไบต์)
  3. คำขอ AJAX แบบสำรวจระยะยาวครั้งแรก
  4. คำขอ AJAX ที่มีความยาวเป็นอันดับสอง
  5. คำขอ AJAX แบบสำรวจความยาวที่สาม
  6. อัพเกรดการเชื่อมต่อเป็น WebSocket

ภาพหน้าจอ

ผลลัพธ์ WebSocket ที่ฉันได้รับจาก localhost:

ผลลัพธ์ WebSocket - โมดูล websocket-vs-socket.io

ผลลัพธ์ Socket.IO ที่ฉันได้รับจาก localhost:

ผลลัพธ์ Socket.IO - โมดูล websocket-vs-socket.io

ทดสอบด้วยตัวเอง

เริ่มต้นอย่างรวดเร็ว:

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

เปิดhttp: // localhost: 3001 /ในเบราว์เซอร์ของคุณเปิดเครื่องมือสำหรับนักพัฒนาด้วย Shift + Ctrl + I เปิดแท็บเครือข่ายแล้วโหลดหน้าเว็บอีกครั้งด้วย Ctrl + R เพื่อดูปริมาณการใช้เครือข่ายสำหรับรุ่น WebSocket

เปิดhttp: // localhost: 3002 /ในเบราว์เซอร์ของคุณเปิดเครื่องมือสำหรับนักพัฒนาด้วย Shift + Ctrl + I เปิดแท็บเครือข่ายแล้วโหลดหน้าเว็บอีกครั้งด้วย Ctrl + R เพื่อดูปริมาณการใช้เครือข่ายสำหรับเวอร์ชั่น Socket.IO

วิธีถอนการติดตั้ง:

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

ความเข้ากันได้ของเบราว์เซอร์

ข้อมูล ณ เดือนมิถุนายน 2559 WebSocket ใช้งานได้กับทุกอย่างยกเว้น Opera Mini รวมถึง IE ที่สูงกว่า 9

นี่เป็นความเข้ากันได้ของเบราว์เซอร์ของ WebSocket บนฉันสามารถใช้ณ มิถุนายน 2559:

ป้อนคำอธิบายรูปภาพที่นี่

ดูhttp://caniuse.com/websocketsสำหรับข้อมูลที่ทันสมัย


23
ดังนั้นโดยทั่วไปสิ่งที่คุณกำลังพูดคือ websocket นั้นดีกว่า socket.io?
Jack Moscovi

42
@ JackMoscovi ฉันจะไม่พูดว่า WebSocket จำเป็นต้องดีกว่า ทุกอย่างขึ้นอยู่กับข้อกำหนด ข้อดีของ WebSocket คือมาตรฐานเว็บ (เป็นครั้งแรกภายใต้ W3C และ whatwg ปัจจุบันอยู่ภายใต้ IETF โดยมี RFC เผยแพร่เมื่อ 5 ปีที่แล้ว) มีน้ำหนักเบามากเพราะรองรับเบราว์เซอร์เป็นอย่างดี ไม่ใช่สากล Socket.IO รองรับเบราว์เซอร์มากขึ้นและมีฟังก์ชันการทำงานที่มากขึ้น บางครั้งคนหนึ่งดีกว่าบางคนอื่น มันเหมือนกับการเลือกระหว่าง querySelectorAll และ jQuery - คำตอบไม่เหมือนกันเสมอ
rsp

20
คำตอบที่ดีที่นี่ !! ดูเหมือนว่าฉัน socket.io ไม่จำเป็นอีกต่อไปในหลายกรณี ... ดูบทความที่ดีนี้ด้วย! medium.com/@ivanderbyl/…
Alvaro

4
@rsp ฉันไม่คิดว่าตัวอย่างเหล่านี้เทียบเท่ากับการใช้งานจริงเหรอ? Socket-io จัดการสิ่งต่าง ๆ เช่นการเชื่อมต่ออัตโนมัติอีกครั้งเมื่อถูกขัดจังหวะ (ซึ่งเกิดขึ้นบนอุปกรณ์มือถือ) และฉันคิดว่ามีข้อกังวลด้านความปลอดภัยเกี่ยวกับสิ่งที่จัดการให้คุณ ตัวอย่าง WS ธรรมดาของคุณในขณะที่เทียบเท่ากับการทำงานไม่มีคุณสมบัติเหล่านี้
mindplay.dk

28
การเปรียบเทียบที่ดีมาก อย่างไรก็ตามเป็นเรื่องที่น่าสังเกตว่า Socket.io เพิ่มการเว้นวรรคชื่อห้องรายละเอียดการเชื่อมต่อจำนวนมากรายละเอียดการบันทึกจำนวนมากและมีไลบรารีการรวมจำนวนมากสำหรับ Socket.IO ด้วย Angular, Vue, React และอื่น ๆ สิ่งสำคัญที่สุดคือคุณสามารถปิดการใช้งานโพลอาแจ็กซ์โพลและเชื่อมต่อโดยตรงผ่าน WebSocket เช่นเดียวกับการเชื่อมต่อ WebSocket แบบดิบ ด้วยวิธีนี้คุณจะได้รับทุกอย่างยกเว้นไลบรารี 180kb เท่ากัน การใช้ WebSocket โดยตรงนั้นเป็นเรื่องที่เจ็บปวดเว้นแต่คุณจะต้องใช้ค่าต่ำสุด การปล่อยห้องและการเข้าถึง IP ชุมชนน่ากลัวสำหรับองค์กร
Nick Steele

30

ฉันจะให้ข้อโต้แย้งกับการใช้ socket.io

ฉันคิดว่าการใช้ socket.io เพียงอย่างเดียวเพราะมันมีทางเลือกไม่ใช่ความคิดที่ดี ให้ IE8 RIP

ในอดีตมีหลายกรณีที่ NodeJS เวอร์ชันใหม่แตก socket.io คุณสามารถตรวจสอบรายการเหล่านี้สำหรับตัวอย่าง ... https://github.com/socketio/socket.io/issues?q=install+error

หากคุณไปพัฒนาแอพ Android หรือบางอย่างที่จำเป็นต้องใช้กับแอพที่มีอยู่คุณอาจจะทำงานกับ WS ได้ทันที socket.io อาจทำให้คุณมีปัญหา ...

นอกจากนี้โมดูล WS สำหรับ Node.JS นั้นใช้งานง่ายอย่างน่าอัศจรรย์


สิ่งที่คุณแนะนำให้เราใช้ในการโต้ตอบกับ mysql -> express.js / fastify.js หรือ node.js โดยตรง ... เพื่อสร้างแอปสำหรับ Android และ iOS แชท
DragonFire

25

การใช้ Socket.IO นั้นเหมือนกับการใช้ jQuery - คุณต้องการรองรับเบราว์เซอร์รุ่นเก่าคุณต้องเขียนโค้ดให้น้อยลงและไลบรารี่จะได้รับข้อมูลสำรอง Socket.io ใช้เทคโนโลยีเว็บซ็อกเก็ตถ้ามีและหากไม่มีให้ตรวจสอบประเภทการสื่อสารที่ดีที่สุดที่มีอยู่และใช้งาน


3

แม้ว่าเบราว์เซอร์ที่ทันสมัยรองรับ WebSockets ในขณะนี้ฉันคิดว่าไม่จำเป็นต้องทิ้ง SocketIO และยังคงมีอยู่ในโครงการปัจจุบัน เป็นเรื่องง่ายที่จะเข้าใจและโดยส่วนตัวฉันเรียนรู้วิธีการทำงานของ WebSockets ด้วย SocketIO

ตามที่กล่าวไว้ในหัวข้อนี้มีไลบรารีการรวมจำนวนมากสำหรับ Angular, React, ฯลฯ และประเภทคำจำกัดความสำหรับ TypeScript และภาษาการเขียนโปรแกรมอื่น ๆ

อีกจุดที่ฉันจะเพิ่มความแตกต่างระหว่าง Socket.io และ WebSockets คือการทำคลัสเตอร์กับ Socket.io ไม่ใช่เรื่องใหญ่ Socket.io เสนอAdaptersที่สามารถใช้เชื่อมโยงกับ Redis เพื่อเพิ่มความยืดหยุ่น คุณมีioredisและsocket.io-Redisตัวอย่างเช่น

ใช่ฉันรู้แล้วว่าSocketClusterมีอยู่จริง แต่นั่นไม่ใช่หัวข้อ


2

Socket.IO ใช้ WebSocket และเมื่อ WebSocket ใช้ไม่ได้จะใช้ทางเลือกสำรองเพื่อทำการเชื่อมต่อแบบเรียลไทม์


0

https://socket.io/docs/#What-Socket-IO-is-not (ด้วยการเน้นของฉัน)

สิ่งที่ Socket.IO ไม่ใช่

Socket.IO ไม่ใช่การใช้งาน WebSocket แม้ว่า Socket.IO จะใช้ WebSocket เป็นการขนส่งเมื่อเป็นไปได้ แต่จะเพิ่มข้อมูลเมตาบางส่วนลงในแต่ละแพ็คเก็ต: ประเภทแพ็กเก็ตเนมสเปซและรหัสแพ็กเก็ตเมื่อจำเป็นต้องมีการตอบรับข้อความ นั่นคือเหตุผลที่ไคลเอ็นต์ WebSocket จะไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ Socket.IO ได้สำเร็จและไคลเอ็นต์ Socket.IO จะไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ WebSocketได้ โปรดดูข้อกำหนดโปรโตคอลที่นี่

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.