<style> @import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'); .reveal { font-family: "Roboto Mono", monospace; font-size: 40px; } </style> # Socket.IO Overview --- ## What is Socket.IO? * Used for real-time applications (need to see changes immediately, without having to refresh the page) * Examples * Instant messenger * Push notifications * Collab apps (Google Drive, etc.) * Online Gaming ---- * Uses open connections between the client and server to facilitate realtime communication * Allows bi-directional communication * TLDR; whenever an event occurs (like a client sends a new message), the server will receive the event and push it to the connected clients (no refreshes!) --- ## How Socket.IO works * Emits information from one client to the server, then the server emits that information to the rest of the clients * All clients can emit events to the server --- ## Example: Chat app * With sockets, when the server receives a new message, it will send it to the client and notify them about the changes * DON'T need to send requests between the client and server ---- ## How would this work without Socket.IO? * Client 1 would send a POST request to add a new message to the database * Client 1 - 3 would need to then send a GET request to get the new array of messages from the database (usually by reloading) * This is not how chat apps should work!! --- ## Installations * Express: ```npm i express``` * Server Socket.IO: ```npm i socket.io``` * Client Socket.IO: ```npm i socket.io-client``` ---- ## Setting up Socket.IO on the server We will set up Socket.IO in our main server file (index.js) ```javascript= const app = require("express")(); const server = app.listen(5000, () => console.log("listening on port 5000")) const io = require("socket.io")(server); /* * listens for a connection event and runs the function after * connection event auto emitted when bi-directional connection * io.on event handler handles connection, disconnection events in it * Each specific socket is a channel between a client and server, a.k.a. * each client has its own socket */ io.on("connection", function(socket){ // user entering page causes "connection" event to emit console.log("user connected"); // when someone leaves page, the disconnect event is emitted socket.on('disconnect', function(){ console.log("a user disconnected") }) }) ``` ---- Whenever a user goes onto our page, "user connected" will be logged, and whenever the user closes the page, "a user disconnected" will be logged. ---- ## Setting up Socket.IO on the client Inside of a React component, add the following ```javascript= import socketIOClient from "socket.io-client"; import React, {Component} from 'react'; class App extends Component { constructor() { super(); this.state = { // same as server, which the socket is listening on endpoint: "http://localhost:5000" }; } componentDidMount() { const { endpoint } = this.state; // create a new client socket with the given endpoint const socket = socketIOClient(endpoint); // wait for a "someEvent" event to emit, then run the function socket.on("someEvent", eventData => console.log(eventData)); } render(){ ... } } ``` ---- The server may emit a "someEvent" event, and when that emits, this client will run the provided function. ---- ## Emit an event from the client and receive on the server ```javascript= // inside client const socket = socketIOClient(endpoint); socket.emit('clientEvent', {/* some data */}); ``` ``` javascript= //inside server io.on('connection', socket => { // when a client emits clientEvent, will do something with the sent data socket.on('clientEvent', data => { // do something with the data }) }) ``` ---- It works the same if you emitted an event from the server and listened for it in the client ---- ## Broadcasting events **Broadcasting**: send a message to all connected clients, clients on a namespace, or clients in a particular room ---- ## Broadcast to all connected clients ```javascript= /* * In index.js */ // on the server, so this counter won't reset until server ends var numClients = 0; io.on("connection", socket => { // keep track of number of users that have connected numClients++; io.sockets.emit("broadcast", {text:`${numClients} clients connected`}) }) ``` ---- ```javascript= /* * In the client */ var socket = socketIOClient(endpoint); socket.on("broadcast", data => { console.log(data); }) ``` --- ## Example: Setting up a chat room! * We would have multiple clients (whoever is apart of the chat room) * Any client can have data (the message that the user typed) and can send that data to the server when the user sends the message * Server receives data and emit it down every other WebSocket to every other client * The clients in the frontend would display the new message ---- ## What would happen in the frontend? * When the send button is clicked, get the text that was typed (stored in state!) and use it to emit a "message" event with the text as data ```javascript= socket.emit("message", {message: this.state.message}); ``` ---- ## How would the server handle the "message" event? * Inside of ```io.on("connection", socket => {...})```, we want to have an event listener to listen for the "message" event ```javascript= // this socket refers to the specific socket connecting the server and the client sending the message socket.on("message", data => { // do something with data }) ``` ---- ## What do we want to do with the new message on the server? We want to send it out to all clients connected to the server! ---- ```javascript= socket.on("message", data => { // io.sockets refers to all sockets connected to server // got the data from a specific client, now emit that message to all clients io.sockets.emit("message", data); }) ``` ---- Now in the frontend, we want to receive this "message" event, since this message event will be carrying the new message that one of the client's just sent! ---- ```javascript= // inside of the frontend, listen for the message event socket.on("message", data => { // append new message to state's message array this.setState(prevState => { const messageList = prevState.messageList.push(data.message); // return the new state to update the state return {messageList} }) }) ```
{"metaMigratedAt":"2023-06-15T04:11:12.744Z","metaMigratedFrom":"Content","title":"Socket.IO Overview","breaks":true,"contributors":"[{\"id\":\"0ffe3cdf-ee91-4b9a-9e67-32d09c41aec9\",\"add\":21,\"del\":1},{\"id\":\"25be75a2-9a21-4137-a70a-c55f361a5189\",\"add\":7607,\"del\":1079}]"}
    241 views
   Owned this note