-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12-socketio.html
161 lines (131 loc) · 7.25 KB
/
12-socketio.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<section id="socketio">
<section>
<h2>Socket.io</h2>
</section>
<section>
<h3>Présentation</h3>
<div class="container">
<div class="col">
<p>Socket.io est un package permettant de créer des applications <strong>temps réel</strong>.</p>
<p>Il permet de simplifier l'utilisation des <strong>WebSockets</strong> et permet également d'utiliser d'autres solutions techniques si le navigateur ou le serveur ne supportent pas cette technologie.</p>
</div>
<div class="col">
<img src="assets/images/socketio.png" alt="Socket.io">
</div>
</div>
</section>
<section>
<h3>Diagramme de séquence</h3>
<img src="assets/images/socketio-sequence-diagram.png" alt="SocketIO diagramme de séquence">
</section>
<section>
<h3>Installation</h3>
<p>Socket.io s'installe en utilisant NPM :</p>
<pre><code class="language-js">npm install --save socket.io</code></pre>
<p>Il faut également installer une librairie côté frontend (client) : <a href="https://github.com/socketio/socket.io-client" target="_blank">socket.io-client</a></p>
</section>
<section>
<h3>Installation</h3>
<p>Pour fonctionner, socket.io doit être lié à une instance de http.Server. Il ne sera donc pas possible de passer une variable <code class="language-js">app</code> d'Express.</p>
<p>Nous allons donc devoir modifier le code par défaut d'Express pour faire fonctionner socket.io :</p>
<pre><code class="language-js">const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server);
server.listen(8000);</code></pre>
<footer>
<a href="https://socket.io/docs/#Using-with-Express" class="info" target="_blank">Installation avec Express</a>
</footer>
</section>
<section>
<h3>Utilisation côté serveur</h3>
<p>Côté serveur, il sera dans un premier temps nécessaire de créer une connexion :</p>
<pre><code class="language-js">io.on('connection', socket => { /* Gestion de la connection */ });</code></pre>
<p>Ensuite, il sera possible d'émettre des événements :</p>
<pre><code class="language-js">socket.emit('customevent', { hello: 'world' });</code></pre>
<p>Et de recevoir des énévements :</p>
<pre><code class="language-js">socket.on('anotherevent', data => console.log(data));</code></pre>
</section>
<section>
<h3>Utilisation côté client</h3>
<p>Côté client, il faudra dans un premier temps se connecter au serveur :</p>
<pre><code class="language-js">var socket = io.connect('http://localhost:8000');</code></pre>
<p>Ensuite, il sera possible d'émettre des événements :</p>
<pre><code class="language-js">socket.emit('customevent', { hello: 'world' });</code></pre>
<p>Et de recevoir des énévements :</p>
<pre><code class="language-js">socket.on('anotherevent', function(data) { console.log(data); });</code></pre>
</section>
<section>
<h3>Namespaces</h3>
<p>Il est possible de créer des namespaces pour isoler les channels de communication.</p>
<p>Par défaut, le namespace utilisé est "/" mais il est possible de créer de nouveaux namespaces :</p>
<pre><code class="language-js">const nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
});</code></pre>
<p>Il sera ensuite possible de se connecter à ce namespace dans le navigateur :</p>
<pre><code class="language-js">var socket = io('http://localhost:8000/my-namespace');</code></pre>
</section>
<section>
<h3>Rooms</h3>
<p>A l'intérieur de chaque namespace, il est également possible de définir plusieurs channels que les internautes pourront rejoidre.</p>
<p>Côté serveur, vous pouvez utiliser <code class="language-js">join</code> pour rejoindre un channel :</p>
<pre><code class="language-js">io.on('connection', function(socket){
socket.join('some room');
});</code></pre>
<p>Puis <code class="language-js">to</code> pour émettre des événements :</p>
<pre><code class="language-js">io.to('some room').emit('some event');</code></pre>
</section>
<section>
<h3>Cheatsheet</h3>
<p>La documentation de socket.io propose une cheatsheet pour émettre des événements :</p>
<pre style="max-height: 300px;"><code class="language-js">io.on('connect', onConnect);
function onConnect(socket){
// sending to the client
socket.emit('hello', 'can you hear me?', 1, 2, 'abc');
// sending to all clients except sender
socket.broadcast.emit('broadcast', 'hello friends!');
// sending to all clients in 'game' room except sender
socket.to('game').emit('nice game', "let's play a game");
// sending to all clients in 'game1' and/or in 'game2' room, except sender
socket.to('game1').to('game2').emit('nice game', "let's play a game (too)");
// sending to all clients in 'game' room, including sender
io.in('game').emit('big-announcement', 'the game will start soon');
// sending to all clients in namespace 'myNamespace', including sender
io.of('myNamespace').emit('bigger-announcement', 'the tournament will start soon');
// sending to a specific room in a specific namespace, including sender
io.of('myNamespace').to('room').emit('event', 'message');
// sending to individual socketid (private message)
io.to(`${socketId}`).emit('hey', 'I just met you');
// WARNING: `socket.to(socket.id).emit()` will NOT work, as it will send to everyone in the room
// named `socket.id` but the sender. Please use the classic `socket.emit()` instead.
// sending with acknowledgement
socket.emit('question', 'do you think so?', function (answer) {});
// sending without compression
socket.compress(false).emit('uncompressed', "that's rough");
// sending a message that might be dropped if the client is not ready to receive messages
socket.volatile.emit('maybe', 'do you really need it?');
// specifying whether the data to send has binary data
socket.binary(false).emit('what', 'I have no binaries!');
// sending to all clients on this node (when using multiple nodes)
io.local.emit('hi', 'my lovely babies');
// sending to all connected clients
io.emit('an event sent to all connected clients');
};</code></pre>
<footer>
<a href="https://socket.io/docs/emit-cheatsheet/" class="info" target="_blank">Doc socket.io</a>
</footer>
</section>
<section>
<h3>Exercice</h3>
<div class="instructions">
<ol>
<li>Créer une page web affichant à intervalle aléatoire un carré rouge</li>
<li>Lorsque le carré apparaît, les internautes doivent cliquer le plus rapidement possible sur un bouton</li>
<li>L'utilisateur ayant cliqué le plus rapidement gagne</li>
<li>Si l'utilisateur clique avant que le carré n'apparaisse, il est disqualifié</li>
<li>Ajouter un système d'authentification</li>
<li>Ajouter la possibilité de créer des rooms</li>
</ol>
</div>
</section>
</section>