socket io những câu lệnh bạn cần biết version 4.0

Nội dung bài viết

Socket io là gì?

Hôm nay quay lại dự án mà theo khách hàng là không sử dụng firebase mà phải sử dụng socket.io anh em à. Cũng chả biết lý do gì mà Khách Hàng mình chả muốn sử dụng firebase nữa, mặc dù firebase có nhiều tính năng có sẵn có thể làm serverless cũng được, và đặc biệt mình rất mạnh về firebase nhé, nhìn sơ qua các thủ thuật sử dụng firebase cũng thấy ghê ghê rồi, nhưng biết sao giờ. Vậy cho nên hôm nay quay lại Socket.io mà nó lên version 4.0 luôn rồi. Hồi xưa khi mình làm nhớ là 2.0 thôi. Hic lâu quá rồi nên phải làm lại thôi. Mở đầu là ghi lại những socket io emit cheat sheet để cho việc sử dụng dễ dàng hơn. Đó cũng là một thói quen tốt của mình hehe...

Phần 2: Demo ứng dụng chat với express, socket io và deploy lên heroku (KÈM SOURCE)

Socket io performance

Khi bắt đầu sử dụng thì hồi đó con server của mình có 4 core mà mình có thể chịu tải cho 8000 Users rồi. Không biết bây giờ 4.0 thì cải thiện được performance khi sử dụng với Node.js không nữa? Thôi để từ từ ghi lại cho Anh em. Bây giờ thì tạm ghi lại những lệnh quan trọng khi sử dụng thằng socket.io này. À nếu anh em nào, biết vì sao ông cha ta hồi xưa nếu không có realtime databse thì ông cha ta làm bằng cách nào không? Nếu không đọc bài "Lịch sử của realtime database" để hiểu rõ hơn.

Socket io cheat sheet

Ở đây chia ra hai phần chính đó là Server-sideClient-side:

Server-side:

io.on("connection", (socket) => {

  // Sử dụng emit cơ bản
  socket.emit(/* ... */);

  //  Gửi tất cả clients có trong namespace trừ thẳng gửi ra
  socket.broadcast.emit(/* ... */);

  //  Gửi cho những thằng có mặt trong room1 trừ thằng gửi ra.
  socket.to("room1").emit(/* ... */);

  // Gửi cho những thằng có mặt trong room1 or và room2  trừ thằng gửi ra.
  socket.to(["room1", "room2"]).emit(/* ... */);

  // Gửi cho những thằng có mặt trong room1 bao gồm thằng gửi.
  io.in("room1").emit(/* ... */);

  // Gửi cho những thằng có mặt trong room1hoặc và room2 ngoại trừ room3 bao gồm thằng gửi.
  io.to(["room1", "room2"]).except("room3").emit(/* ... */);

  //  Gửi cho tất cả các thằng có trong namespace "myNamespace"
  io.of("myNamespace").emit(/* ... */);

  // Gửi cho tất cả các thằng có trong room1 và  có  namespace "myNamespace"
  io.of("myNamespace").to("room1").emit(/* ... */);

  // Gửi cho các nhân với nhau giống như  (private message)
  io.to(socketId).emit(/* ... */);

  //  Cái này mới, chưa biết sao nhưng nó dùng để gửi cho tâtr cả client trong một nod. Chắc là cluster node.js
  io.local.emit(/* ... */);

  //  Gửi cho tất cả Client đã connec rồi.
  io.emit(/* ... */);

  // with acknowledgement
  socket.emit("question", (answer) => {
    // ...
  });

  //  không nén dữ liệu khi gửi, hinh như mặc định là có.
  socket.compress(false).emit(/* ... */);

  // a message that might be dropped if the low-level transport is not writable
  socket.volatile.emit(/* ... */);

})

Client-side:

// basic emit
socket.emit(/* ... */);

// with acknowledgement
socket.emit("question", (answer) => {
  // ...
});

// without compression
socket.compress(false).emit(/* ... */);

// a message that might be dropped if the low-level transport is not writable
socket.volatile.emit(/* ... */);

volatile socket io

Một trong những sự kiện mà trước đây có nhiều bạn không hiểu hay thắc mắc đó là sự kiện volatile socket. Khi chưa connect thực sự sẵn sàng thì khi server emit cũng không hoạt động, vi dụ sau đây sẽ giúp bạn hình dung hơn khi nói.

Giả sử Client cứ mỗi giây nhận tín hiệu xem server có hoạt động không thì code sẽ như sau:

// server-side
io.on("connection", (socket) => {
  console.log("connect");

  socket.on("ping", (count) => {
    console.log(count);
  });
});

// client-side
let count = 0;
setInterval(() => {
  socket.volatile.emit("ping", ++count);
}, 1000);

Kết quả sẽ cho ra khi chúng ta restart server nếu sử dụng volatile.

connect
1
2
3
4
# Server đã restarted, client tự động kết nối
connect
9
10
11

Vậy nếu không sử dụng volatile trong trường hợp trên thì sao:

connect
1
2
3
4
# Server đã restarted, client tự động kết nối và tự động chạy lại những hành động trước đó
connect
5
6
7
8
9
10
11

Tránh sử dụng socket io sau đây

Dưới đây là những sự kiện được dành riêng cho hệ thống, khi đặt tên sự kiện, mấy cha nội vui lòng né ra. Đặt trùng tên là chết mịa đấy:

  • connect
  • connect_error
  • disconnect
  • disconnecting
  • newListener
  • removeListener

Ví dụ cho một cái chết được báo trước:

// BAD, will throw an error
socket.emit("disconnecting");

Ngoài ra đó là việc khai tử socket.to(socket.id).emit(), lúc trước dùng để nhắn tin 1-1 hay là private message đó. Nhưng giờ nếu làm vậy theo tài liệu nói là push hết đến mọi người trong room đấy. Vãi...

  // WARNING: `socket.to(socket.id).emit()` will NOT work, as it will send to everyone in the room
  // named `socket.id` but the sender. Please use the classic `socket.emit()` instead.

Tóm lại

Trên đây là phần 1 cho việc tìm hiểu và sử dụng socket.io, tôi vừa join vào dự án. Cho nê sẽ update cho các bạn những task tiếp theo.

XIn chào!!

Có thể bạn đã bị missing