Heim  >  Artikel  >  Web-Frontend  >  Einführung in das Socket.io-Lerntutorial in node.js (3)

Einführung in das Socket.io-Lerntutorial in node.js (3)

零下一度
零下一度Original
2017-05-03 10:02:191147Durchsuche

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(&#39;room name&#39;) //进入 
socket.leave(&#39;room name&#39;) //退出
io.to(&#39;some room&#39;).emit(&#39;some event&#39;) // io.to与io.in同义,向某个聊天室的所有成员发送消息

默认聊天室

每个socket在连接成功后会自动创建一个默认个聊天室,这个聊天室的名字是当前socket的id,可以通过默认聊天室实现向特定用户发送消息

socket.on(&#39;say to someone&#39;, (id, msg) => { 
 socket.broadcast.to(id).emit(&#39;my message&#39;, msg)
})

消息发送

应答消息

普通消息不需要回应,而应答消息提供了应答机制

io.on(&#39;connection&#39;, socket => { 
 socket.emit(&#39;an event&#39;, { some: &#39;data&#39; }) //普通消息

 socket.emit(&#39;ferret&#39;, &#39;tobi&#39;, function (data) { //应答消息
 console.log(data); // data will be &#39;woot&#39;
 })
})


socket.on(&#39;ferret&#39;, (name, fn) => { 
 fn(&#39;woot&#39;)
})

压缩

socket.compress(true)启用压缩,调用后当前连接的所有数据在传递给客户端前都会进行压缩

volatile标志

socket.io在正常情况下对发送的消息进行追踪,确保消息发送成功,而设置volatile后发送消息,socket.io不会对消息追踪,消息可能丢失

分类

// 客户端发送消息
socket.emit(&#39;hello&#39;, &#39;can you hear me?&#39;, 1, 2, &#39;abc&#39;);

// 向所有连接的客户端(除了自己)发送消息
socket.broadcast.emit(&#39;broadcast&#39;, &#39;hello friends!&#39;);

// 向game聊天室发送消息,自己不算
socket.to(&#39;game&#39;).emit(&#39;nice game&#39;, "let&#39;s play a game");

// 同时向game1和game2聊天室发送消息,自己不算
socket.to(&#39;game1&#39;).to(&#39;game2&#39;).emit(&#39;nice game&#39;, "let&#39;s play a game (too)");

// 向game聊天室的所有人发送消息
io.in(&#39;game&#39;).emit(&#39;big-announcement&#39;, &#39;the game will start soon&#39;);

// 发送消息到<socketid>客户端
socket.to(<socketid>).emit(&#39;hey&#39;, &#39;I just met you&#39;);
// 发送应答消息
socket.emit(&#39;question&#39;, &#39;do you think so?&#39;, 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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn