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:

socket.io docs

websocket on wikipaediea

tutorials point: socket.io

educba: websocket vs socket.io