Heim > Artikel > Web-Frontend > Einführung in das Socket.io-Lerntutorial in node.js (3)
Dieser Artikel führt Sie ausführlicher in die grundlegenden Tutorials und Anwendungen von socket.io ein. In diesem Artikel wird die Verwendung von socket.io ausführlicher vorgestellt Sie können es als Referenz verwenden. Werfen wir einen Blick darauf.
Vorwort
Socket.io bietet bidirektionale Echtzeitkommunikation basierend auf Ereignissen. Let's Schauen Sie sich den detaillierten Inhalt an.
Statische Dateien
socket.io stellt socket.io.min standardmäßig über das socket.io-client-Paket bereit js und socket.io.js.map
Führen Sie die Instanz app.js aus
let app = require('http').createServer() let io = require('socket.io')(app) app.listen(3000);
Browserzugriff http://localhost:3000/socket.io/socket io .js kann komprimierten Quellcode laden. Besuchen Sie http://localhost:3000/socket.io/socket.io.js.map, um die Quellkarte zu laden
Wir können dieses Verhalten ändern
Socket.io.js-Download deaktivieren
Methode 1: Übergeben Sie den Steuerparameter „serveClient value false“ bei der Instanziierung
let io = require('socket.io')(app, { serveClient: false })
Methode 2 : Rufen Sie die Funktion serverClient auf
let app = require('http').createServer() let io = require('socket.io')() io.serveClient(false) io.listen(app) // 或者io.attach(app)
Wenn der Dienst vor dem Aufruf der Funktion gebunden wurdehttp.Server
, funktioniert diese Methode nicht
Wenn Sie nach dem Deaktivieren erneut darauf zugreifen, wird dies der Fall sein werden Sie dazu aufgefordert{"code":0,"message":"Transport unknown"}
Ändern Sie den statischen Dateipfad
Der Pfad von socket.io.js kann geändert werden, und zwar Der Standardpfad ist /socket.io.
Beim Instanziieren Parameter übergeben
let io = require('socket.io')(app, { path: '/io' })
Funktionspfad aufrufen
let app = require('http').createServer() let io = require('socket.io')() io.path('/io') io.listen(app)
Wenn der Dienst vor dem Aufruf der Funktion gebunden wurdehttp.Server
, funktioniert diese Methode nicht Funktion
Sicherheitsrichtlinie
socket.io bietet zwei Sicherheitsrichtlinien
allowRequest
Die FunktionallowRequest hat zwei Parameter. Der erste Parameter ist das empfangene Handshake-Paketobjekt (http.request
), das als Grundlage für die Beurteilung und den Erfolg verwendet wird. Err ist das Fehlerobjekt success ist boolean, false bedeutet, dass der Verbindungsaufbau verhindert wird
Die Front-End-Anfrage bringt Token
let socket = io('http://localhost:3000?token=abc') socket.on('connect', () => { console.log('connect') }) socket.on('connect_error', err => { socket.disconnect() console.log('connect_error', err) })
Die Back-End-allowRequest bestimmt anhand des Tokens, ob fortgefahren werden soll
let app = require('http').createServer() let io = require('socket.io')(app, { allowRequest: (req, cb) => { if (req._query && req._query.token === 'abc') return cb(null, true) cb(null, false) } });
Ursprünge
Sie können die Quelle einschränken
1. Begrenzen Sie die Quelle beim Instanziieren
let app = require('http').createServer() let io = require('socket.io')(app, { origins: 'http://localhost:3000' })
2 . Die Ursprungsfunktion legt die Quelle fest
Die Ursprungsfunktion hat zwei Formen
origins(string)
: Legen Sie die Quelle der Operation fest
origins(string, fn(err, success))
: Verwenden Sie die Funktion, um zu bestimmen, ob die Quelle zulässig ist
io.origins('http://localhost:*') io.origins((origin, cb) => { if (origin === 'http://localhost:3000/') return cb(null, true) cb(null, false) })
Namespace
Namespace wird zum Isolieren verwendet Mancherorts werden Namensräume auch als Kanäle (Channel) bezeichnet. Das folgende Beispiel erklärt seine Bedeutung
Wir müssen eine kollaborative Anwendung implementieren, die zwei Funktionen hat:
Gemeinsame Bearbeitung: Mehrere Benutzer können ein Dokument gleichzeitig bearbeiten
Nachricht: Benutzer können Nachrichten zwischen Benutzern senden
Verwenden Sie socket.io, um diese Anwendung zu implementieren, die die folgenden Formen hat
1. Völlig unabhängig: Die kollaborative Bearbeitung verfügt über einen unabhängigen Dienst edit.socket.test
und das Nachrichtensystem verfügt über einen unabhängigen Dienst message.socket.test
let editSocket = io('edit.socket.test') let messageSocket = io('message.socket.test')
2. Namespace: Es wird nur ein unabhängiger Dienst ausgeführt , durch den Namespace Isolation
let app = require('http').createServer() let io = require('socket.io')(app) let editServer = io.of('/edit') let messsageServer = io.of('/message') editServer.on('connection', socket => { //编辑相关 }) messsageServer.on('connection', socket => { /消息相关 })
let editSocket = io('socket.test/edit') let messageSocket = io('socket.test/message')
3. Ereignisnamenskonvention: Isolierung durch Hinzufügen von Ereignisnamen
let app = require('http').createServer() let io = require('socket.io')(app) io.on('connection', socket => { //编辑相关 io.emit('edit:test') io.on('edit:test', data => { }) //消息相关 io.emit('message:test') io.on('message:test', data => { }) }
Das Verfahren zur Ereignisnamenskonvention ist zu aufdringlich und einer Aufteilung nicht förderlich und Neuorganisation, nicht empfohlen. Der völlig unabhängige Modus erfordert die Verwendung von zwei Socket-Verbindungen, wodurch die vom Browser zugelassene Anzahl gleichzeitiger Verbindungen verschwendet wird und mehr Serverressourcen verbraucht werden. Durch die Verwendung von Namespaces kann eine gute Isolierung erreicht werden, ohne dass Ressourcen verschwendet werden.
Standard-Namespace
Der Namespace mit Pfad / wird automatisch gebunden, wenn socket.io instanziiert wird
let app = require('http').createServer() let io = require('socket.io')(app) io.sockets // io.of('/').sockets io.emit // 代理io.of('/').emit, 类似函数有'to', 'in', 'use', 'send', 'write', 'clients', 'compress'
Middleware
Der Namespace von socket.io registriert die Middleware durch die Verwendung und die Middleware stellt erfolgreich eine Verbindung zwischen dem Client und dem Server her. Schließlich wird es einmal aufgerufen, bevor das Connet-Ereignis ausgelöst wird.
Middleware zur Datenüberprüfung verwenden
io.use((socket, next) => { if (socket.request.headers.cookie) return next() next(new Error('Authentication error')) })
Middleware zum Extrahieren oder Konvertieren von Daten verwendenio.use((socket, next) => { <code>io.use((socket, next) => { <br>getInfo(socket.request.query.id, (err, data) => { if (err) return next(err) socket.custom = data next() }) })
getInfo(socket . request.query.id, (err, data) => { if (err) return next(err) socket.custom = data next() }) })
Verglichen mitallowRequest
allowRequest kann einige Überprüfungen und Extraktionen durchführen. Warum brauchen wir Middleware?
allowRequest eingehende http.request-Instanz, während die Middleware Betritt und verlässt die Daten-Socket-Instanz, die Socket-Instanz enthält die Anforderungsinstanz und verfügt über weitere Informationen
Die Middleware unterstützt direkt die Verschachtelung mehrerer asynchroner Prozesse, während AllowRequest von Ihnen selbst implementiert werden muss
Vergleich mit Verbindungsereignis
Das Verbindungsereignis wird auch in den Socket übergeben und kann auch für numerische Zwecke verwendet werden Verifizierung und Extraktion. Warum? Benötigen Sie Middleware?
Middleware unterstützt direkt die Verschachtelung mehrerer asynchroner Prozesse, während AllowRequest selbst implementiert werden muss
中间件成功后到connection事件发送成功前,socket.io还做了一些工作,比如把socket实例添加到connected对象中,加入聊天室等。如果因为权限中断连接,在中间件中处理更省资源.
聊天室
聊天室是对当前连接的socket集合根据特定规则进行归组,方便群发消息。可以类比QQ群的概率.
socket.join('room name') //进入 socket.leave('room name') //退出
io.to('some room').emit('some event') // io.to与io.in同义,向某个聊天室的所有成员发送消息
默认聊天室
每个socket在连接成功后会自动创建一个默认个聊天室,这个聊天室的名字是当前socket的id,可以通过默认聊天室实现向特定用户发送消息
socket.on('say to someone', (id, msg) => { socket.broadcast.to(id).emit('my message', msg) })
消息发送
应答消息
普通消息不需要回应,而应答消息提供了应答机制
io.on('connection', socket => { socket.emit('an event', { some: 'data' }) //普通消息 socket.emit('ferret', 'tobi', function (data) { //应答消息 console.log(data); // data will be 'woot' }) })
socket.on('ferret', (name, fn) => { fn('woot') })
压缩
socket.compress(true)
启用压缩,调用后当前连接的所有数据在传递给客户端前都会进行压缩
volatile标志
socket.io在正常情况下对发送的消息进行追踪,确保消息发送成功,而设置volatile后发送消息,socket.io不会对消息追踪,消息可能丢失
分类
// 客户端发送消息 socket.emit('hello', 'can you hear me?', 1, 2, 'abc'); // 向所有连接的客户端(除了自己)发送消息 socket.broadcast.emit('broadcast', 'hello friends!'); // 向game聊天室发送消息,自己不算 socket.to('game').emit('nice game', "let's play a game"); // 同时向game1和game2聊天室发送消息,自己不算 socket.to('game1').to('game2').emit('nice game', "let's play a game (too)"); // 向game聊天室的所有人发送消息 io.in('game').emit('big-announcement', 'the game will start soon'); // 发送消息到<socketid>客户端 socket.to(<socketid>).emit('hey', 'I just met you'); // 发送应答消息 socket.emit('question', 'do you think so?', function (answer) {});
Das obige ist der detaillierte Inhalt vonEinführung in das Socket.io-Lerntutorial in node.js (3). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!