Real Time notification using Python Flask (flask_socketio) and React

91 Views Asked by At

Everyone.

I encountered some issues in implementing Real-time notification using Flask and React.

Server side Flask code

from flask import Flask, request
from flask_cors import CORS
from flask_socketio import SocketIO, emit
from utils import *
from lib.auth import *
from dotenv import load_dotenv
load_dotenv()

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
CORS(app)
socketio = SocketIO(app, cors_allowed_origins="*")

################# SocketIO ###################
@socketio.on("connect")
def connected():
    """event listener when client connects to the server"""
    print(request.sid)
    print("client has connected")
    emit("connect",{ "data": f"id: {request.sid} is connected"})

@socketio.on("disconnect")
def disconnected():
    """event listener when client disconnects to the server"""
    print("user disconnected")
    emit("disconnect",f"user {request.sid} disconnected", broadcast=True)

if __name__  == "__main__":
    socketio.run(app, debug=True, port=8888, host='0.0.0.0')

Client Side React Code

apis/socket.js

import { io } from "socket.io-client";

export const socket = io("http://localhost:8888", {
    transports: ['websocket'],
    cors: {
        origin: "http://localhost:3000"
    }
});

PrivateLayout.js

import * as React from "react";
import Box from "@mui/material/Box";
import LinearProgress from "@mui/material/LinearProgress";
import { Navigate, useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
import { useSnackbar } from "notistack";
import { useAuth } from "../hooks/useAuth";
import Sidebar from "../components/Sidebar";
import { store } from "../redux/store";
import jwtDecode from "jwt-decode";
import { apis } from "../apis";
import { strings } from "../constants/strings";
import { socket } from "../apis/socket";
import Header from "../components/Header";
import { SET_CURRENT_USER } from "../redux/actionTypes";

export default function PrivateLayout({ children, isAdmin }) {
  const { user } = useSelector((state) => state.auth);
  const { isLoading } = useSelector((state) => state.common);
  const navigate = useNavigate();
  const { enqueueSnackbar } = useSnackbar();
  const { token } = useAuth();

  React.useEffect(() => {
    socket.on('connect', function() {
      alert('socket connected')
    })

    return () => {
      socket.disconnect()
    }
  }, []);


  const GetUserById = async (id) => {
    try {
      const res = await apis.getUserbyId(id);
      store.dispatch({
        type: SET_CURRENT_USER,
        payload: res.result
      })
    } catch (err) {
      enqueueSnackbar({
        variant: "error",
        message: err.response?.data.error || strings.SERVER_ERROR,
      });
    }
  }

  React.useEffect(() => {
    if (token) {
      const decodedToken = jwtDecode(token);
      GetUserById(decodedToken.id)
    }
  }, [token]);

  React.useEffect(() => {
    if (user) {
      if (isAdmin && user.role !== "superadmin") {
        navigate('/dashboard');
      }
    }
  }, [user])

  if (!token) return <Navigate to={`/login`} />;
  else
    return (
      <Box sx={{ display: "flex" }}>
        <Sidebar />
        <Box sx={{ flex: 1 }}>
          <Header />
          {isLoading && <LinearProgress sx={{ mr: 2, ml: 2 }} />}
          <Box component="main" flex={1} overflow="auto" p={2}>
            {children}
          </Box>
        </Box>
      </Box>
    );
}

When I run frontend, I can see "client has connected" message in log. But it doesn't stop and keeps appearing.

enter image description here

In frontend side, I got following errors.

enter image description here

enter image description here

I am waiting for your help.

Thanks

0

There are 0 best solutions below