如何在 typescript 上从 express 控制器发出 socket.io 事件?

How to emit socket.io event from express controller on typescript?

我正在学习 socket.io 和打字稿。我目前正在构建一个应用程序,我想在 client.For 后端的数据库更改上发出事件,我正在使用 Express、typescript 和 nodeJS

我看过很多帖子,但我不明白如何访问我的 io 实例以便能够从我的控制器函数发出我的事件。此外,大多数示例都在 javascript 上,这更令人困惑。

目前在我的 app.ts 我有以下配置。我如何在我的控制器函数中移动我的 addOnlineHandler、logOutHandler 和 sendNotificationHandler,以便能够直接从控制器的 createOrder 函数发出数据库更改事件?

我试过在控制器中导入所有 orderHandler 函数,但它不起作用。我无法访问 io 实例来发出事件。

app.ts

import  express  from "express";
import dotenv from "dotenv";
import userRoute from './routes/user'
import mongoose from "mongoose";
import { createServer } from "http";
import { Server,Socket } from "socket.io";
import {addOnlineShopHandler,logOutHandler, sendNotificationHandler} from "./socket/orderHandler";


dotenv.config();
const app = express();

const httpServer = createServer(app);

const io = new Server(httpServer, {
    cors:{
        origin:"*"
    }
});

const onConnection = (socket:Socket) => {
    addOnlineShopHandler(socket)
    logOutHandler(socket)
    sendNotificationHandler(socket)
    
  }

io.on("connection",onConnection)


httpServer.listen(process.env.PORT, () => {
    console.log('Backend server is running')
});

const connectToDatabase = async (dbConnectionString:string) => {
    await mongoose.connect(dbConnectionString)
    console.log('Connection to DB sucess')
}

connectToDatabase(`${process.env.MONGO_URI}`).catch(err => console.log(err))

app.use('/api/users',userRoute)

我的控制器文件,我需要在其中能够在创建订单时发出事件。

orderController.ts

import { RequestHandler } from "express";


export const createOrder:RequestHandler = async (req, res) => {
    // I want to use socket.io in this function 
    // emit event when order created 


}

我的 orderHandler 文件。

orderHandler.ts

import { Server,Socket } from "socket.io";

interface IOnlineShop {
    shopId:string, 
    socketId:string
}

let onlineShop:IOnlineShop[] = []

export const addOnlineShopHandler = (socket:Socket) => {
    console.log('someone is in')
    
    const addNewShop = (shopId:string, socketId:string) => {
        !onlineShop.some((currentShop) => currentShop.shopId === shopId) && onlineShop.push({shopId,socketId})
    }
    const newShopConnected = (shopId:string) => {
        addNewShop(shopId,socket.id)
    }

    socket.on('newShopConnected',newShopConnected)

}

export const logOutHandler = (socket:Socket) => {

    const removeShop = (socketId:string) => {
        onlineShop = onlineShop.filter((currentShop)=>{currentShop.socketId !== socketId})
        console.log('someone is out')
    }
    socket.on('disconnect',removeShop)
    
}


export const sendNotificationHandler = (socket:Socket) =>{
    const getUser = (shopId:string) =>{
        return onlineShop.find((currentShop) => currentShop.shopId === shopId)}
    const sendNotification = (data:any) =>{
        const receiver = getUser('randomshopId')
        console.log(receiver)
    }

    socket.on("sendNotif",sendNotification)
}


我已经看过这些帖子,但仍然无法解决问题,也许使用打字稿让我感到困惑。对工作流程的任何帮助或解释将不胜感激。 how to use socket.io in controller file Use socket.io in controllers

谢谢,

您可以将 io 附加到应用程序对象:

app.set('io', io);

然后您可以使用 req.app.get('io')

从控制器中访问它