ბერტი და ერნი, ორი მეგობარი, ერთად მუშაობენ თავიანთი ოცნების გვერდით პროექტზე: ჩეთის აპლიკაცია, რომელიც საშუალებას აძლევს რეალურ დროში საუბრებს გუნდებისთვის, რომლებიც მუშაობენ დისტანციურად. ფრონტ-ენდის კოდირებელი ბერტი ძლივს იკავებდა თავს, რადგან ის უზიარებს ბრწყინვალე ახალ ფუნქციებს თავის ბექენდის სპეციალისტ მეგობარს. „შეხედე! მე შემიძლია აკრიფო შეტყობინება და ის იგზავნება სერვერზე და ვხედავ პასუხს, რომელიც თითქმის მყისიერად გამოჩნდება!” ერნი, ბექენდის გურუ, შუბლშეკრულია. „მაგრამ როგორ გადაჭრით საკითხი, რომ ორი ადამიანი ერთდროულად ცდილობს საუბარს? თქვენი აპი აგრძელებს გვერდის განახლებას იმის ნაცვლად, რომ გაჩვენოთ საუბარი, რაც შეუძლებელს ხდის ჩეთს რეალურ დროში. ”
გამოწვევა ის არის, რომ ბერტის აპი მუშაობს HTTP-ზე, რომელშიც კლიენტმა უნდა მოითხოვოს სერვერიდან მიღება. ერნი აჯამებს: „თითქოს ყველა შენი მეგობარი გიგზავნის მესიჯს, მაგრამ შემდეგ, მოულოდნელად, ვერ ნახავ ვერცერთ პასუხს, სანამ არ განაახლებ, რათა შეამოწმო არის თუ არა ახალი შეტყობინებები, რადგან ისინი ვერ ხედავენ თქვენს ბოლო შეტყობინებას, სანამ არ განაახლებთ და ასე მუშაობს HTTP!
აქ არის საუკეთესო ნაწილი: სრული დასტა აპებისთვის, რომლებიც რეალურ დროში მუშაობენ, არის WebSockets. ეს ნაწილი ძალიან საინტერესოა, ასე რომ, მოდით შევუერთდეთ ერნის და ბერტს და გავარკვიოთ, როგორ ფუნქციონირებს WebSockets, მათი განხორციელების პროცედურები, მათი მნიშვნელობის მსჯელობა და მრავალი სხვა.
WebSockets მსგავსია უწყვეტი სატელეფონო ზარისა კლიენტს (თქვენი ვებ ბრაუზერი) და სერვერს შორის. ისინი განსხვავდებიან HTTP პროტოკოლისგან, რომელიც ფუნქციონირებს „წერილის გაგზავნა, პასუხის მოლოდინში“. WebSockets-ით ორივე მხარეს შეუძლია თავისუფლად ისაუბროს, როგორც მოესურვება. WebSockets-ის მახასიათებლები მოიცავს შემდეგს:
მაგალითი: წარმოიდგინეთ მუდმივად განახლებული სპორტული ანგარიში. HTTP-ით კლიენტს მუდმივად უწევს სერვერის სპამის გაგზავნა ყოველ წამში, „რამე ქულის ცვლილება?“ WebSockets-ით, სერვერი აცხადებს "GOAL!" მყისიერად მოხდება.
ბერტი უკან ზის და თავს იკრავს. ”მაგრამ HTTP კარგად მუშაობს აპების უმეტესობისთვის. რატომ გადაიტანეთ კარის ძელები?” ერნი რბილად იცინის, იღებს მარკერს და იწყებს რაღაცის წერას დაფაზე.
"მოდით დავიწყოთ ზემოდან," ამბობს ის. „ვთქვათ რეალურ დროში ცხოვრების განახლებები, როგორიცაა ცოცხალი სპორტული ქულები. კლიენტებმა ყოველ წამს უნდა ჰკითხონ სერვერს: „არის რამე, რაც უნდა ვიცოდე?“ ეს არის გამოკითხვა, ასე რომ, ყოველ ოცდაათ წამში, თქვენ უნდა გკითხოთ, "ვიკრიბებით?" სასაცილოა, არა? ის ასევე იყენებს უამრავ გამტარობას. ”
WebSockets აბრუნებს ამას:
„HTTP საკმაოდ წესიერია სტატიკურ საკითხებთან გამკლავებაში, როგორიცაა ბლოგი ან პროდუქტის გვერდი. თუმცა, როდესაც საქმე ეხება ცოცხალ ურთიერთქმედებებს, საჭიროა მუდმივი კავშირი. ვებსოკეტები“.
ერნი სათვალეს იწმენდს. "მაშ, მოდით შევქმნათ მარტივი ჩეთის აპლიკაცია", - იძახის ერნი. "ჩვენ გვექნება Node.js სერვერი ბექენდისთვის და React აპი ფრონტენდისთვის. მზად ხართ?"
„აიღეთ Node.js სერვერი, რადგან ის დაგჭირდებათ Socket.IO ნაწილისთვის“, - ამბობს ერნი, როდესაც ის ძალიან სწრაფად წერს:
npm init -y npm install express socket.io
სერვერის კოდი (server.js):
const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const app = express(); const server = http.createServer(app); const io = new Server(server); // Serve static files (like React's build folder) app.use(express.static('public')); // Handle WebSocket connections io.on('connection', (socket) => { console.log('New user connected:', socket.id); // Listen for Incoming messages from the socket socket.on('sendMessage', (message) => { console.log('Received:', message); // Broadcast the message to everyone io.emit('receiveMessage', message); }); // Handle user disconnects events socket.on('disconnect', () => { console.log('User left:', socket.id); }); }); server.listen(3000, () => { console.log('Visit http://localhost:3000 on a browser, Server started successful on port 3000'); });
„კლიენტს და სერვერს შეუძლიათ ერთმანეთთან კომუნიკაცია Socket.IO-ს მიერ WebSocket კავშირების დამუშავების წყალობით. როდესაც კლიენტი იძახებს (sendMessage) ფუნქციას, სერვერი აგზავნის შეტყობინებას ყველასთვის, ვინც დაკავშირებულია (io.emit) საშუალებით. საკმაოდ პირდაპირი, არა?
„ახლა ჩემი ჯერია. მოდით ვიმუშაოთ React კლიენტზე“, - ამბობს ბერტი.
npx create-react-app chat-client cd chat-client npm install socket.io-client
ჩატის კომპონენტი (Chat.js):
import { useState, useEffect } from 'react'; import io from 'socket.io-client'; // Connect to the server const socket = io('http://localhost:3000'); function Chat() { const [message, setMessage] = useState(''); const [messages, setMessages] = useState([]); useEffect(() => { // Listen for new messages socket.on('receiveMessage', (newMessage) => { setMessages([...messages, newMessage]); }); }, [messages]); const sendMessage = () => { if (message.trim()) { socket.emit('sendMessage', message); setMessage(''); } }; return ( <div style={{ padding: '20px' }}> <div> {messages.map((msg, index) => ( <p key={index}>{msg}</p> ))} </div> <input value={message} onChange={(e) => setMessage(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && sendMessage()} /> <button onClick={sendMessage}>Send</button> </div> ); } export default Chat;
როგორ მუშაობს:
გამოცადე:
ეს არის ის, რის შექმნაც ბერტს აპირებდა აპლიკაციის საფუძველზე, მაგრამ ერნი აღნიშნავს, რომ „რეალური აპლიკაციების უმეტესობას სჭირდება შეცდომების დამუშავება და განვითარების ჩარჩოს გაფართოების გზა“. ვნახოთ რამდენიმე სავარაუდო პრობლემა.
განახორციელეთ ხელახალი დაკავშირების სტრატეგია React კლიენტში.
socket.on('disconnect', () => { console.log('Disconnected. Trying to reconnect...'); socket.connect(); // Auto-reconnect });
დაიცავით WebSocket ავტორიზებული JWT ტოკენების გამოყენებით.
// On login, send a token socket.emit('authenticate', { token: 'USER_JWT' }); // Server verifies token socket.on('authenticate', ({ token }) => { if (isValidToken(token)) { socket.authenticated = true; } else { socket.disconnect(); } });
დანერგეთ შეტყობინებების გადაცემა სხვადასხვა სერვერებს შორის Redis-ის გამოყენებით.
npm install redis
სერვერის კოდი:
const redis = require('redis'); const subscriber = redis.createClient(); subscriber.subscribe('chat-channel'); subscriber.on('message', (channel, message) => { io.emit('receiveMessage', message); });
ჩეთის მიღმა: გაზიარებული დოკუმენტის რედაქტირება
ეს არის ბერტის შემდეგი იდეა - Google Docs-ის მსგავსი რედაქტორი. ერნი ამბობს: „შეგიძლიათ გამოიყენოთ ვებ სოკეტები სხვადასხვა ადამიანების მიერ განხორციელებული ცვლილებების მოსასმენად და მათი გაერთიანებისთვის“.
მაგალითად:
მომხმარებელი A ტიპის: "გამარჯობა"
მომხმარებელი B ხსნის "o"-ს და ამატებს ", World"
სერვერი უსმენს კლავიშის თითოეულ დარტყმას და გადასცემს მას ყველა კლიენტს, რათა მათმა კლიენტებმა განაახლონ განახლებული დოკუმენტი.
კოდის ნაწყვეტი:
// Client sends keystrokes textarea.addEventListener('input', (e) => { socket.emit('textChange', e.target.value); }); // Server broadcasts changes socket.on('textChange', (text) => { io.emit('updateText', text); });
ერნი გვაფრთხილებს, რომ: „არასოდეს არ გამოიყენოთ WebSockets HTTPS/WSS გარეშე!“
const io = new Server(server, { cors: { origin: "https://yourdomain.com" }, });
დაადასტურეთ ყველა შეყვანა ისე, რომ მოხდეს ნებისმიერი მონაცემის გასუფთავება, რამაც შეიძლება გამოიწვიოს XSS შეტევები.
განახორციელეთ განაკვეთის ლიმიტი სპამის ქცევის მქონე მომხმარებლებზე.
კითხვა: WebSockets-ის სიჩქარე ბევრად უკეთესია, ვიდრე HTTP?
A: დიახ! მყისიერი აპლიკაციებისთვის, WebSockets საუკეთესოა, რადგან ისინი ხსნიან გამოკითხვის ჩატარების აუცილებლობას.
Q: შესაძლებელია თუ არა REST API-ების გამოყენება WebSockets-თან ერთად?
_ დიახ, აუცილებლად! გამოიყენეთ WebSockets პირდაპირი განახლებებით და REST CRUD ოპერაციების შესასრულებლად.
კითხვა: როგორ გავუმკლავდე სერვერის ავარიას?
A: კლიენტებს შეუძლიათ ავტომატურად ხელახლა დაკავშირება (იხ. ხელახლა დაკავშირების ლოგიკა ზემოთ).
ბერტის ჩეთის აპი ახლა რეალურ დროში მომხიბვლელობით ირეკება და ერნი კმაყოფილი იღიმება. WebSockets არ არის მხოლოდ ჩეთებისთვის, არამედ ემსახურება ცოცხალი დაფის, თამაშების, IoT და სხვა მიზნებს.
შენი ჯერი: წადი და სცადე მაგალითები, გაანადგურე ისინი და შექმენი რაღაც ახალი. თქვენი რეალურ დროში აპლიკაციები გელოდებათ!