Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 7093

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T12:36:09+00:00 2024-11-28T12:36:09+00:00

WebSockets Unlocked: Mastering the Art of Real-Time Communication

  • 60k

Hey there! 🌟 Ready to dive into the exciting world of real-time communication with WebSocket? πŸš€ Join me in this series where we'll start from the basics, craft awesome chat/video apps, and master scaling with Redis and Kafka. Get set for a journey filled with interactive learning! πŸŒπŸ’¬βœ¨ #RealTimeWeb #WebSocketAdventures

Learning about websockets can be a bit tricky at first, but once you get the hang of it, it becomes quite easy. I would definitely recommend taking the time to learn about websockets, as they are an essential part of modern web development and can greatly enhance the real-time capabilities of your applications. Plus, mastering websockets opens up a whole new world of possibilities for interactive and dynamic web experiences. So, don't be discouraged by the initial challenges – the rewards of learning websockets are well worth the effort!

This blog serves as an introduction to websockets, explaining what they are and why you should consider building your application using websockets. It also covers the difference between http and websockets, as well as the benefits of using websockets.

You can only learn by building so in this blog we will also learn how to build a basic message application using websockets with Socket.io, Node.js, and React.

What is websocket

WebSockets are a communication protocol that provides full-duplex communication channels over a single, long-lived connection. Unlike traditional HTTP connections, which are stateless and involve the client making a request and the server responding, WebSockets allow for bidirectional communication between the client and server. This is built on top of TCP/IP, which means it is reliable and ensures that every packet is received.

HTTP is like sending letters where you ask for something, and then you wait for a reply. WebSocket is like having a phone call where you can talk back and forth instantly. Chat applications, online gaming, financial platforms, and live streaming is build using websockets.

Working of websockets
let's look at some benefits of websocket

Full-duplex Communication can be imagine like using walkie-talkies where you and your friend can talk and listen at the same time. Full-duplex is like having a chat where both can speak without waiting, and that's how WebSockets let computers talk back and forth instantly.

Persistent Connection means once you connect your device to the internet (or a server), the link stays open as long as needed. It's like staying on a call without hanging up, making communication faster and more efficient.

Low Latency means there's minimal delay when sending and receiving information. It's like a really fast text conversation.

WebSockets use a ws:// or wss:// URI scheme, where ws stands for WebSocket and wss is WebSocket Secure (encrypted using TLS/SSL).

Playing with websockets

You might be asking where can you start using WebSocket and how can you use this well, Modern web browsers provide a WebSocket API that allows developers to work with WebSockets using JavaScript. This API includes methods for opening a WebSocket connection, sending and receiving messages, and handling events.

Open a web browser (Chrome, Edge, Safari, Brave) and type ctrl + shift + i to open the developer tools. Then, go to the console tab and write the following command.

  // Create a variable called socket with a URL (echo wss) let socket = new WebSocket("wss://ws.postman-echo.com/raw");  // Define a function to respond to the data received on the socket socket.onmessage = function(event) {     console.log('Message received: ' + event.data); };  // Send a message using the socket.send() method socket.send('Hello, server!');   
Enter fullscreen mode Exit fullscreen mode

wss://ws.postman-echo.com/raw (postman echo websocket server)

As you can see, we are creating a variable called “socket” which has a URL (echo wss). We are also defining a function which will respond to the data received on the socket. We are sending a message using the “socket.send()” method.

playing in console 1

Now, move to the network tab and find the raw name response. You can see that this raw response is of type websocket.

Clicking on raw will allow you to see additional information about the request, such as the status code and headers.

playing in console 2

Click on the message tab to view all the WebSocket messages that have been sent and received. The UpArrow denotes the message sent by us, while the DownArrow denotes the message received. Since we are using an echo server, we are getting the same response (refer to the previous image).

playing in console 3

Go ahead and try this out on your own and experiment with it. You can also learn more about the WebSocket API on the MND documentation.

Building a simple chat application

Learning without building is not effective, which is why we are going to create a simple chat application where users can send and receive messages in real time.

src code

ui for application

This is a basic app. We will build the proper UI in future blogs. Let's start coding.

Make sure you have node installed

  node --version   
Enter fullscreen mode Exit fullscreen mode

I am using Node.js version v20.10.0. Any version above v18.17 should work.

Create the project folder containing two sub-folders named client and server.

  mkdir chat-app cd chat-app mkdir client server   
Enter fullscreen mode Exit fullscreen mode

folder structure

Server

Next, navigate into the server folder and create a package.json file.

  cd server npm init -y   
Enter fullscreen mode Exit fullscreen mode

Install Socket.io Server API,We would be using TypeScript for a better developer experience (DX) and take advantage of tsc-watch for constant reloading.

  # Add socket.io npm add socket.io  # Add dev dependencies npm add -D tsc-watch typescript  # Preinstalled tsc globally tsc --init   # Change tsconfig.json  "rootDir": "./src",     "outDir": "./dist",                       # start the server in dev npm dev   
Enter fullscreen mode Exit fullscreen mode

set scripts in package.json

  {   "name": "server",   "version": "1.0.0",   "main": "index.js",   "license": "MIT",   "scripts": {     "dev": "tsc-watch --onSuccess "node dist/index.js"",     "build": "tsc -p .",     "start": "node dist/index.js"   },   "devDependencies": {     "tsc-watch": "^6.0.4",     "typescript": "^5.3.3"   } }   
Enter fullscreen mode Exit fullscreen mode

Lets start by creating a basic server using the built-in http module and start the server.

  # index.ts  import http from "http";  async function init() {   const httpServer = await http.createServer();    const PORT = process.env.PORT ? process.env.PORT : 8000;    httpServer.listen(PORT, () => {     console.log(`http server started at ${PORT}...`);   });  }  init();   
Enter fullscreen mode Exit fullscreen mode

  npm run dev   
Enter fullscreen mode Exit fullscreen mode

if you see this everything is working as expected

Now we will be implementing socket logic using socket.io for building websockets. This library provides an abstraction layer on top of WebSockets, simplifying the process of creating real-time applications. For better maintainability, it is recommended to create a separate file for socket calls. To do this, navigate to the src folder, create a folder named services, and inside it, create a file named socket.ts under the services folder.

Here are the commands to create a class called SocketService which initializes a socket connection. You can obtain this connection by using the getIo() method and export this class.

  # services/socket.ts import { Server } from "socket.io";  class SocketService {    // Create a variable _io with type Server from socket.io   private _io: Server;    constructor() {     // Log a message when the SocketService is initialized     console.log("init socket server");      // Setup CORS policy to allow all ('*')     this._io = new Server({       cors: {         origin: "*",         allowedHeaders: ["*"],       },     });   }    // Initialize event listeners for the socket connection   public initListeners() {     // Get a reference to the _io instance     const io = this._io;      // Event listener for when a client connects to the WebSocket server     io.on("connect", async (socket) => {       // Log a message when a client connects, including their socket id       console.log(`⚑ userId ${socket.id} connected`);        // Log a message when socket user is disconnected       socket.on("disconnect", () => {         console.log(`🚫 userId ${socket.id} disconnected`);       });     });   }    // Getter method to access the _io instance from outside the class   get io() {     return this._io;   } }  // Export the SocketService class as the default export of this module export default SocketService;   
Enter fullscreen mode Exit fullscreen mode

initListeners() method This method initializes event listeners for the WebSocket server. In this case, it sets up a listener for the “connect” event, which fires when a client connects to the server. It logs a message indicating the user id (socket id) of the connected client.

get io() method : This getter method allows external components to access the _io instance from outside the class.

Now add a event listener for message event this block will run when the server recevies a messages

  // Event listener for "event:message" socket.on("event:message", (msg) => {   // Log the received message to the server console   console.log("message received", msg);    // Emit a "message" event to all clients with the received message   io.emit("message", JSON.stringify(msg)); });   
Enter fullscreen mode Exit fullscreen mode

start server 1

Import the SocketService to create a new socket instance and attach the socket to the server. Then, initialize all the listeners.

  # index.ts  import http from "http"; // import socket service  import SocketService from "./services/socket";  async function init() {   const httpServer = await http.createServer();    // initializing the socket server    const socketService = new SocketService();   const PORT = process.env.PORT ? process.env.PORT : 8000;    // attaching the server to the SocketService   socketService.io.attach(httpServer);    httpServer.listen(PORT, () => {     console.log(`http server started at ${PORT}...`);   });    // initialize the socket listeners   socketService.initListeners(); }  init();   
Enter fullscreen mode Exit fullscreen mode

start the server

  npm run dev   
Enter fullscreen mode Exit fullscreen mode

start server 2

as you can see the socket server is initialize and server is working on 8000 and a user is connected

Server work is done hereπŸ₯³πŸ₯³

Client

Navigate to the client folder using your terminal and then create a new Next.js project with Tailwind CSS and TypeScript.

learn more about

  • Next.js

  • typescript

  • tailwindcss

  cd client npx create-next-app@latest ./  # options  # tailwindcss typescript app/   
Enter fullscreen mode Exit fullscreen mode

Install socket.io-client, socket.io a library that provides an abstraction layer on top of WebSockets, simplifying the process of creating real-time applications.

  npm install socket.io-client   
Enter fullscreen mode Exit fullscreen mode

Create a folder called context and add a file SocketProvider.tsx. This file serves as a wrapper around the app, allowing us to use the socket from anywhere within the app.

  // context/SocketProvider.tsx  import React, {  createContext,  useCallback,  useContext,  useEffect,  useState } from 'react' import { Socket, io } from 'socket.io-client'  // Interface defining the structure of the SocketContext interface ISocketContext {   messages: string[]   socket: any   sendMessage: (msg: string) => void }   const SocketContext = createContext<ISocketContext | null>(null)  // Custom hook for easily accessing the socket context export const useSocket = () => {   const state = useContext(SocketContext);   if (!state) throw new Error(`state is undefined`);   return state; }  export const SocketProvider: React.FC<{      children: React.ReactNode  }> = ({ children }) => {    // State to hold the socket instance    const [socket, setSocket] = useState<Socket>()   // To hold all messages in socket connection   const [messages, setMessages] = useState<string[]>([])    // function to send a message from chat   const sendMessage: ISocketContext["sendMessage"] = useCallback(     (msg: string) => {         console.log("sending msg...", msg)         if (!socket) throw new Error("socket not ready")         // emit event to send message from socket         socket?.emit("event:message", { message: msg })   }, [socket])     const onMessageReceived = useCallback((msg: string) => {     const { message } = JSON.parse(msg) as { message: string }     // Set the msg received in the messages state     setMessages((prev) => [...prev, message])   }, [])    // Effect to set up the socket connection when the component mounts   useEffect(() => {     // Create a new socket instance     const _socket = io("http://localhost:8000")      // Set up an event listener for the "message" event     // This function if fired when the `message` is received from the backend     _socket.on("message", onMessageReceived)      // Set the socket instance in the state     setSocket(_socket)      // Cleanup function to disconnect the socket when the component unmounts      // for better performace     return () => {       setSocket(undefined)       _socket.disconnect();       _socket.off("message", onMessageReceived)     }   }, [])    // Provide the socket context to the wrapped components   return (     <SocketContext.Provider value={{ socket, messages, sendMessage }}>       {children}     </SocketContext.Provider>   ) }   
Enter fullscreen mode Exit fullscreen mode

The SocketContext defines a context named SocketContext that will hold the socket instance, messages, and a function to send messages.

The SocketProvider Component is a React functional component that wraps the entire application. It sets up the WebSocket connection, manages messages, and provides the socket context to its children.

The useEffect hook runs when the component mounts. It creates a new socket instance, sets up event listeners, and cleans up the socket and listeners when the component unmounts.

The useSocket Hook is a custom hook that uses the useContext hook to access the socket context. It throws an error if the context is not available.

Wrap the socket provider around the app to enable access to the socket from any part of the application.

  // layout.tsx  import type { Metadata } from 'next' import { Inter } from 'next/font/google' import './globals.css' import { SocketProvider } from '@/context/SocketProvider'  const inter = Inter({ subsets: ['latin'] })  export const metadata: Metadata = {   title: 'Create Next App',   description: 'Generated by create next app', }  export default function RootLayout({   children, }: {   children: React.ReactNode }) {   return (     <html lang="en">        // This socketProvier will provide the state variable to all the        // cihldrens       <SocketProvider>         <body className={inter.className}>{children}</body>       </SocketProvider>     </html>   ) }   
Enter fullscreen mode Exit fullscreen mode

Creating a Chat Application Layout and Design Using Tailwind CSS

To create the layout and design for a chat application, we will be using Tailwind CSS. In order to mark the file as a client component, we will utilize socket works as the client component only.

The handleSubmit function is called when the user submits a message. It checks if the message is not empty, clears the input field, and can potentially handle sending the message .

  // page.tsx "use client"  import { useState } from "react" import { useSocket } from "@/context/SocketProvider"  export default function Home() {   const [message, setMessage] = useState('')   const { messages, sendMessage } = useSocket()    const handleSubmit = () => {     if (message === "") return;     setMessage('');      sendMessage(message)   }     return (     <div className="m-10 h-[600px] flex flex-col border-2 rounded-md border-white p-2">       <div className="h-full overflow-y-auto flex flex-col p-2 overflow-x-hidden gap-1">         // space for displaying chat       </div>       <div className="flex ">         <input           onChange={(e) => setMessage(e.target.value)}           type="text"           value={message}           placeholder="message..."           onKeyDown={(e) => {             if (e.key === "Enter") {               handleSubmit()             }           }}           className="bg-zinc-700 w-full px-6 py-2 rounded-md"         />         <button           onClick={() => handleSubmit()}           className="px-6 py-2 border-2 border-white rounded-md"         >           send         </button>       </div>     </div >   ) }   
Enter fullscreen mode Exit fullscreen mode

We can import the socket provider that we created earlier to send and display messages. usesocket() is a custom hook that enables us to interact with the state and function create.

Start the development server and open the browser to view the application at http://localhost:3000.

  npm run dev   
Enter fullscreen mode Exit fullscreen mode

Open the application in two different tabs in incognito mode to ensure that it is working properly.

complete working application

πŸ₯³Yaaaaaaay!!!πŸ₯³

Congratulations on building your first chat application using WebSockets!. It looks like you've provided a detailed guide on setting up a chat application using WebSockets with Socket.io, Node.js, and React. This is a comprehensive overview, covering both server and client implementations, as well as the layout and design using Tailwind CSS. Additionally, you've introduced key concepts like Full-duplex Communication, Persistent Connection, and Low Latency associated with WebSockets.

Here's a summary of the blog:

Introduction to WebSockets: Real-time communication using WebSockets for chat and video applications.

Benefits of WebSockets: Full-duplex Communication, Persistent Connection, Low Latency.

**Practical Example:**Connecting to a WebSocket server using browser developer tools.

Building a Simple Chat Application:

  • Setting up the server with Socket.io and Node.js.

  • Creating a basic layout for the chat application using React and Tailwind CSS.

This is just the beginning of your journey into real-time communication. Stay tuned for the next blog where we'll explore the limitations of WebSockets for scaling and how to overcome them.

πŸš€ If you had a blast exploring WebSockets and building that chat app, you're in for a treat! 🌟 This is just the beginning of your journey into real-time communication. Stay tuned for the next blog where we'll explore the limitations of WebSockets for scaling and how to overcome them. Don't forget to share this blog with your tech-savvy pals! Together, we're coding our way to greatness. πŸš€πŸ’» #TechAdventures #StayCurious”

Follow me @Raunak Gurud ❀️⚑

javascriptreacttypescriptwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.