Làm cách nào để triển khai WebSocket trong nodejs?

Giao tiếp thời gian thực chắc chắn đã trở nên phổ biến trong lần đầu tiên từ xa. Có nhiều công nghệ hỗ trợ phát triển ứng dụng RTM. Một trong những ngăn xếp công nghệ hiệu quả nhất cho mục đích này kết hợp WebSockets và Node. js. Dưới đây là hướng dẫn từng bước về cách tạo ứng dụng liên lạc theo thời gian thực bằng các giải pháp này

nút. phụ trợ js

Làm cách nào để triển khai WebSocket trong nodejs?

Marcin . Nhà phân tích kỹ thuật giao diện người dùng

21 Tháng Mười

10 phút đọc

Làm cách nào để triển khai WebSocket trong nodejs?

giao tiếp thời gian thực

Hãy bắt đầu với câu hỏi cơ bản. giao tiếp thời gian thực nghĩa là gì? . Xem xét định nghĩa này, một câu hỏi khác xuất hiện - chúng ta có thể gọi khai thác API REST để hỏi về tài nguyên một lần mỗi giây hoặc thậm chí thường xuyên hơn là giao tiếp thời gian thực không?

Làm cách nào để triển khai WebSocket trong nodejs?

Trong trường hợp này, điều đó có nghĩa là chúng tôi sẽ tự động lấy tài nguyên sau khi máy chủ nhận được và truyền nó cho máy khách. Đó là mục đích WebSockets được tạo ra và chúng ta sẽ tìm hiểu chủ đề này trong bài viết sau

WebSockets + Nút. js - một kết hợp hoàn hảo cho RTC

Theo định nghĩa trên trang web Mozilla

API WebSocket là một công nghệ tiên tiến cho phép mở phiên giao tiếp tương tác hai chiều giữa trình duyệt của người dùng và máy chủ. Với API này, bạn có thể gửi tin nhắn đến máy chủ và nhận phản hồi theo sự kiện mà không cần phải thăm dò ý kiến ​​​​của máy chủ để trả lời

Nhưng nó thực sự có nghĩa là gì?

Làm cách nào để triển khai WebSocket trong nodejs?

Nguồn. Microsoft. com

Trong ứng dụng ví dụ về giao tiếp thời gian thực, chúng tôi sẽ kết hợp WebSockets với Node. js. Tại sao vậy? . Nhưng như chúng tôi đã đề cập trong bài viết của anh ấy, động cơ V8 của Node. js chỉ được tạo ra để phục vụ các ứng dụng máy chủ thời gian thực. Bên cạnh đó, nó dựa trên JavaScript giống như JavaScript được sử dụng trong trình duyệt web, vì vậy chúng tôi có thể sử dụng cùng một ngôn ngữ trên cả hai - giao diện người dùng và phụ trợ.  

Ứng dụng giao tiếp thời gian thực từng bước

Vì chúng tôi biết WebSockets là gì và chúng tôi quyết định sử dụng Node. js với nó, bây giờ chúng ta có thể tạo dự án mẫu của mình. Chúng tôi sẽ viết một ứng dụng trò chuyện đơn giản trong đó chúng tôi có thể chỉ định tên của mình và gửi tin nhắn cho người khác

Cây rơm

Chúng tôi sẽ sử dụng Nút. js v14. 11. 0, gói ws và một tính năng mới của Node. js bằng cách nhập mô-đun (bạn có thể tìm hiểu cách thực hiện từng bước tại đây). Để kiểm tra các kết nối WS, chúng tôi có thể chọn Máy khách kiểm tra WebSocket tiện ích mở rộng của Chrome. Đây là công cụ rất đơn giản nhưng hiệu quả cho phép chúng tôi kiểm tra xem kết nối có hoạt động như chúng tôi mong đợi hay không

Cài đặt

Tôi tin rằng bạn đã quen thuộc với Node. js và đã cài đặt nó, nhưng nếu không - chỉ cần tải xuống từ trang web chính thức. Tất nhiên, để bắt đầu dự án của chúng tôi, chúng tôi cũng cần cài đặt gói WebSocket

npm install websocket
// or with yarn
yarn add websocket

Bây giờ chúng ta phải tạo chỉ mục. js nơi chúng tôi sẽ tạo máy chủ Websocket của mình

import WebSocket from 'ws';

const wss = new WebSocket.Server({
  port: 8080,
});

Và thế là xong, chúng tôi đã tạo máy chủ WebSockets đầu tiên của mình. ) Bạn có thể chạy nó từ chỉ mục nút giao diện điều khiển. js

máy chủ websocket

Không giống như các máy chủ HTTP, các máy chủ WebSockets không có bất kỳ tuyến đường nào theo mặc định vì nó không cần thiết. Trong giao thức này, bạn chỉ cần sử dụng một chuỗi để gửi và nhận thông tin (một phương pháp hay là gửi một đối tượng JSON được tuần tự hóa thành một chuỗi). Đó là lý do tại sao cấu hình rất đơn giản, vẫn chưa phải là kết thúc. Bây giờ chúng tôi phải xử lý các kết nối đến máy chủ, nhận dữ liệu từ máy khách và gửi chúng cho những người tham gia khác trong cuộc trò chuyện của chúng tôi

tham gia trò chuyện

Bây giờ chúng tôi có máy chủ cơ bản của mình, chúng tôi có thể kết nối với nó. Để làm như vậy, chúng tôi chỉ cần một địa chỉ và điều này rất đơn giản để đạt được khi chúng tôi chạy nó cục bộ và chúng tôi biết máy chủ lưu trữ sẽ là máy chủ cục bộ. Chúng tôi cũng đã xác định số cổng thành 8080 để URL sẽ là máy chủ cục bộ. 8080 mặc dù bạn không thể chèn mã này vào thanh địa chỉ của trình duyệt - đó không phải là giao thức HTTP/S. Để kết nối với WebSockets, chúng tôi cần ứng dụng khách của nó. Như tôi đã đề cập trước đó, tôi sẽ sử dụng tiện ích mở rộng của Chrome để kết nối nhanh với ổ cắm

Biết địa chỉ của máy chủ và thực tế là webcockets có giao thức riêng, chúng tôi phải thêm ws ngay bây giờ. // ở đầu URL. Để kết nối với máy chủ của chúng tôi, chúng tôi nên cung cấp ws. //máy chủ cục bộ. 8080/ dưới dạng URL

Đừng ngạc nhiên rằng sau khi thiết lập kết nối sẽ không có gì xuất hiện. Chúng tôi chưa có bất cứ thứ gì có thể được trả lại cho các máy khách được kết nối

Làm cách nào để triển khai WebSocket trong nodejs?

Để thông báo cho người dùng rằng họ đang tham gia trò chuyện của chúng tôi, chúng tôi phải gửi cho họ thông tin. Nhưng trước tiên, chúng tôi phải biết rằng một người dùng đã tham gia với chúng tôi. Để đạt được điều này, chúng tôi phải lắng nghe một kết nối sự kiện trong máy chủ của chúng tôi

wss.on('connection', () => {});

kết nối là một trong số ít sự kiện có thể được lắng nghe và sự kiện cụ thể này chịu trách nhiệm thông báo khi một khách hàng mới kết nối với máy chủ của chúng tôi

Nhưng trình lắng nghe sự kiện này không làm gì vào thời điểm này, vì vậy hãy mở rộng nó

Là tham số đầu tiên của cuộc gọi lại, chúng tôi sẽ có một phiên bản websockets của máy khách. Nhờ đó chúng tôi sẽ có thể gửi dữ liệu cho anh ấy

wss.on('connection', (ws) => {
  ws.send('Welcome to the chat, enjoy :)');
});

ws. gửi là một chức năng cho phép chúng tôi gửi dữ liệu đến một máy khách cụ thể vừa kết nối với máy chủ của chúng tôi. Những người tham gia khác đã được kết nối sẽ không nhận được tin nhắn đó

Bây giờ, khi người dùng kết nối với cuộc trò chuyện của chúng tôi, anh ấy sẽ thấy một thông báo thông báo cho anh ấy về điều đó.  

Làm cách nào để triển khai WebSocket trong nodejs?

gửi tin nhắn

Chúng tôi có một máy chủ thông báo cho người dùng khi họ kết nối với máy chủ đó, nhưng còn việc gửi tin nhắn cho những người khác cũng tham gia cuộc trò chuyện của chúng tôi thì sao?

Bây giờ chúng ta phải lấy danh sách này và chuyển dữ liệu cho họ

wss.on('connection', (ws) => {
  ws.send('Welcome to the chat, enjoy :)');

  ws.on('message', (data) => {
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data);
      }
    });
  });
});

Một lần nữa, chúng tôi đang sử dụng trình lắng nghe sự kiện nhưng hiện tại chúng tôi đang thực hiện trên một máy khách cụ thể thay vì toàn bộ máy chủ. Thông báo sự kiện chịu trách nhiệm thông báo khi người dùng gửi cho chúng tôi một tin nhắn mới và trong cuộc gọi lại, chúng tôi đang nhận được nó

Máy chủ của chúng tôi có một danh sách khách hàng và chúng tôi có thể lặp lại danh sách đó. Khi chúng tôi có một máy khách, chúng tôi cần kiểm tra trạng thái kết nối của nó, đó là lý do tại sao chúng tôi kiểm tra xem máy khách có. readyState === WebSocket. MỞ. Nếu trạng thái ổn, chúng tôi sẽ gửi tin nhắn mà chúng tôi nhận được từ khách hàng

Làm cách nào để triển khai WebSocket trong nodejs?

Thật không may, tin nhắn chúng tôi vừa gửi cho người khác cũng đã được gửi cho chúng tôi. Chúng ta có thể thấy điều đó ở phía bên trái - tin nhắn màu đỏ là tin nhắn chúng tôi đã gửi và màu đen là tin nhắn đã nhận. Đôi khi nó hữu ích, nhưng trong hầu hết các trường hợp, không cần thiết. Để ngăn chặn điều đó, chúng tôi phải kiểm tra xem phiên bản WebSockets từ danh sách của máy khách có khác với phiên bản từ máy khách gửi tin nhắn không

if (client !== ws && client.readyState === WebSocket.OPEN)

Nhờ đó, chúng tôi sẽ không nhận được tin nhắn của chính mình

Làm cách nào để triển khai WebSocket trong nodejs?

đối tượng JSON

Bây giờ chúng tôi chỉ gửi tin nhắn và chúng tôi không biết ai đang gửi chúng. Chúng ta có thể thực hiện một số quy ước và, ví dụ, ở đầu tin nhắn, chúng ta sẽ đặt tên tác giả, thêm một số dấu phân cách, sau đó là tin nhắn. Tải trọng sẽ trông giống như

User 1;This is my message text

Nhưng nếu ai đó sẽ có dấu phân cách của chúng tôi trong tên thì sao? . Đây là một cách thực hành tốt với việc sử dụng các đối tượng JSON. Nhờ đó, chúng tôi sẽ tạo một cấu trúc được sử dụng trong ứng dụng của chúng tôi. Vì chúng tôi đang gửi chuỗi, JavaScript sẽ giúp chúng tôi điều này vì chúng tôi có thể dễ dàng lưu đối tượng của mình dưới dạng chuỗi JSON và khôi phục đối tượng từ chuỗi JSON nhờ JSON. xâu chuỗi và JSON. phân tích cú pháp

Chúng tôi chỉ cần kiểm tra máy chủ của mình xem thông báo từ máy khách có phải là chuỗi JSON hợp lệ không. Chúng ta có thể đạt được điều đó bằng cách phân tích cú pháp và lưu vào một biến

let message;

try {
  message = JSON.parse(data);
} catch (e) {
  sendError(ws, 'Wrong format');

  return;
}

const sendError = (ws, message) => {
  const messageObject = {
    type: 'ERROR',
    payload: message,
  };

  ws.send(JSON.stringify(messageObject));
};

Điều này sẽ chuyển đổi dữ liệu thành đối tượng JS và nếu có lỗi xuất hiện, nó sẽ thông báo cho khách hàng về lỗi đó

Bạn có thể nhận thấy rằng chúng ta có một cấu trúc của đối tượng JSON được gửi đến máy khách. Loại cấu trúc này có thể giúp bạn trong tương lai khi bạn thêm một tính năng mới. Chúng tôi cũng sẽ sử dụng nó trong các bước tiếp theo

Loại sẽ thông báo cho chúng tôi về loại tin nhắn mà chúng tôi có thể mong đợi nhận được và tải trọng là nơi chúng tôi sẽ đính kèm nội dung của mình

Vì chúng tôi yêu cầu JSON ngay bây giờ, chúng tôi có thể dễ dàng xác định dữ liệu nào được gửi cho chúng tôi. Tin nhắn mới đến sẽ trông như thế này

________số 8

Bây giờ chúng tôi biết loại tin nhắn mà chúng tôi đã nhận được - đó là NEW_MESSAGE và điều đó cho phép chúng tôi chỉ gửi tin nhắn mới thay vì gửi cho người khác mọi thứ

Hãy chuyển sang kiểm tra loại. Nếu điều này bằng NEW_MESSAGE, chúng tôi sẽ gửi tin nhắn cho người khác

if (message.type === 'NEW_MESSAGE') {
  wss.clients.forEach((client) => {
    if (client !== ws && client.readyState === WebSocket.OPEN) {
      client.send(data);
    }
  });
}

Ứng dụng của chúng ta sẽ trông như thế này

import WebSocket from 'ws';

const wss = new WebSocket.Server({
  port: 8080,
});
0

Qua đó chúng ta có một WebSocket server cơ bản với chat. Bạn có thể tạo giao diện người dùng cho nó bằng cách chọn bất kỳ khung hoặc lib nào bạn thích. Vì chúng tôi đã sử dụng triển khai WebSockets gốc của nút nên chúng tôi có thể sử dụng websockets của trình duyệt

Làm cách nào để triển khai WebSocket trong nodejs?

Mạnh mẽ nhưng dễ dàng

Có nhiều thư viện khác nhau dành cho WebSockets mà bạn có thể sử dụng như ổ cắm. io hoặc autobahn nhưng một số trong số chúng yêu cầu thư viện máy khách đặc biệt như ổ cắm. io hoặc autobahn. Một số trong số chúng có thể phù hợp với mục đích của bạn và một số có thể không phải là một lựa chọn tốt, tôi khuyên bạn nên đọc tài liệu hoặc chỉ cần kiểm tra Google xem thư viện bạn chọn có phải là giải pháp tốt cho vấn đề của bạn không

WebSocket là một công cụ thực sự mạnh mẽ và hữu ích để xây dựng một ứng dụng dựa trên giao tiếp thời gian thực. Hơn nữa, áp dụng nó trong Node. js rất dễ dàng và bạn có thể sử dụng thư viện không yêu cầu bất kỳ gói nào khác trong ứng dụng giao diện người dùng của mình vì các trình duyệt đã tích hợp sẵn thư viện này.  

Làm cách nào để tạo máy chủ WebSocket trong nodejs?

Bên trong thẻ html, chúng ta sẽ viết mã JavaScript để kết nối và tương tác với máy chủ socket . Để kết nối với máy chủ ổ cắm của chúng tôi, chúng tôi sẽ sử dụng hàm tạo WebSocket gốc. Nó tạo một phiên bản ổ cắm mới kết nối với máy chủ ổ cắm được chỉ định bởi đường dẫn chúng tôi cung cấp.

Nodejs có hỗ trợ WebSockets không?

Nút. js có thể duy trì đồng thời hàng trăm kết nối WebSockets . WebSockets trên máy chủ có thể trở nên phức tạp khi quá trình nâng cấp kết nối từ HTTP lên WebSockets yêu cầu xử lý. Đây là lý do tại sao các nhà phát triển thường sử dụng thư viện để quản lý việc này cho họ.

Làm cách nào để sử dụng WSS trong nút js?

Ví dụ sử dụng .
Gửi và nhận dữ liệu văn bản. nhập WebSocket từ 'ws'; . //www. chủ nhà. com/đường dẫn'); . .
máy chủ đơn giản. nhập {WebSocketServer} từ 'ws'; . 8080 }); . .
Sử dụng nút. API luồng js

Nodejs có thể xử lý bao nhiêu WebSocket?

Giới hạn lý thuyết là 65 nghìn kết nối trên mỗi địa chỉ IP nhưng giới hạn thực tế thường giống hơn 20 nghìn, vì vậy chúng tôi sử dụng nhiều địa chỉ để kết nối 20 nghìn .