Socket to ME! - 401-advanced-javascript-aimurphy/seattle-javascript-401n13 GitHub Wiki
*keeping all the socket stuff together, new readings for namespaces and rooms have been added into this wiki!
*Socket.io !== websocket implementation. socket.io client won't be able to connect to a websocket server and visaversa. Socket.io uses websocket as transport but adds metadata to each packet(type, namespace, ack 등...)
Socket.IO is a JavaScript library for real-time web applications (RTAs).
some accolades: most powerful JavaScript frameworks on GitHub, and most depended-upon NPM (Node Package Manager) module. Socket.IO also has a huge community, which means finding help is quite easy
So, RTAs are things like messaging apps, collaborative apps~like google docs, push notifications, etc... apps that run and react immediately with the user.
In olden days it was hard work writing and running RTAs because you had to constantly poll the server, but then websockets became the workaround--leaving the connection open.
OPEN = real time, two-way data flow between client and server
the socket connection is like a pipe between the server and client that stays open and each socket is a connection within the pipe... The user doesn't have to request info, in other words, the server acts like a pubsub to the clients. Clients aren't making ajax requests, the server just emits and clients listen.
WebSocket provides full-duplex comm channels over a single TCP connection. Like HTTP, it's located in layer 7(application) of the OSI model, and relies on TCP, which is in layer 4(transport). It also works on HTTP ports 80 and 443. It is NOT HTTP, and uses the HTTP Upgrade header to change from HTTP to WebSocket protocol.
Namespaces and Rooms!
Namespaces means you can give sockets different endpoints '/'
'/'
is io.sockets
, or io
for short
get personal
call of
on the server side and then tell the clientside socket.io to connect! like this:
//serverside be like~
const nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
});
nsp.emit('hi', 'everyone!');
//clientside be all like~
const socket = io('/my-namespace');
in each namespace you make, you can also create channels for sockets to join and leave! That's the socket.io way of saying subscribe and unsubscribe, or listen and don't.
[more to come on room stuffs]
HELLO FROM THE OTHER SIDE~
sending messages from the outside world
how do you emit to your sockets when you aren't in context? Meet: redis and emitter.
?-redis in your server
?-emitter from your non-socket business
Redis! ADAPTER!(still uses io as io)
const redis = require('socket.io-redis'); io.adapter(redis({ host: 'localhost', port: 6379 }));
Emitter! EMIT! (notice io is io-emitter)
const io = require('socket.io-emitter')({ host: '127.0.0.1', port: 6379 });
setInterval(function(){
io.emit('time', new Date);
}, 5000);
Some Fab Cheats
BTW, you can't use these as eventnames b/c they're already reserved: error
, connect
, disconnect
, disconnecting
, newListener
, removeListener
, ping
, pong
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');
};
sources: