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
Marcin . Nhà phân tích kỹ thuật giao diện người dùng
21 Tháng Mười10 phút đọc
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?
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ì?
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
Để 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 đó.
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
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
đố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ố 8Bâ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,
}];
0Qua đó 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
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.