在node.js中的客户端和服务器js文件之间共享mysql连接

在node.js中的客户端和服务器js文件之间共享mysql连接,mysql,node.js,express,socket.io,Mysql,Node.js,Express,Socket.io,我在这里看到过类似的问题,但没有一个完全像这样,所以我希望我没有重复已经问过的问题 我是node.js&socket.io的新手,所以请耐心听我说,我正在尝试构建一个多聊天室应用程序 我被困在试图将代码分成“模块”的步骤中。我的项目目录结构如下 My index.js启动express服务器并设置基本socket.io连接。据我所知,这个起点index.js文件是“服务器端”js Index.js const path = require('path') const http = requir

我在这里看到过类似的问题,但没有一个完全像这样,所以我希望我没有重复已经问过的问题

我是node.js&socket.io的新手,所以请耐心听我说,我正在尝试构建一个多聊天室应用程序

我被困在试图将代码分成“模块”的步骤中。我的项目目录结构如下

My index.js启动express服务器并设置基本socket.io连接。据我所知,这个起点index.js文件是“服务器端”js

Index.js

const path = require('path')
const http = require('http')
const express = require('express')
const socketio = require('socket.io')
const { generatemsg } = require('./utils/messages')
const { addUser, removeUser, getUser, getUserInRoom } = require('./utils/users')
const pool = require('./utils/dbconfig');
const db = require('../public/js/database');

const app = express()
const server = http.createServer(app)
const io = socketio(server)
const PORT = process.env.PORT || 3000

const publicdir = path.join(__dirname, '../public')

app.use(express.static(publicdir))

io.on("connection", (socket) => {
    console.log("new connection from socket.io")

    socket.on("join", ({ username, room }, cb) => {

        const { error, user } = addUser({ id: socket.id, username, room })

        if (error) {
            return cb(error)
        }
        
        socket.join(user.room)

        //generate random color
        const colorsArray = ["red", "green", "lime", "purple", "blue"]
        var arrayPos = Math.floor(Math.random() * colorsArray.length)
        var colorTmp = colorsArray[arrayPos]

        //Add New User to DB
        var userTmp = user.username
        var roomTmp = user.room
        
        db.addCurrentUserToDB(userTmp, roomTmp, colorTmp)

        io.to(user.room).emit("roomData", {
            room: user.room,
            users: getUserInRoom(user.room)
        })
        
        cb()
    })

    socket.on("sendMessage", (msg, cb) => {
        const user = getUser(socket.id)
        io.to(user.room).emit("message", generatemsg(user.username, msg))
        cb()
    })

    socket.on("disconnect", () => {
        const user = removeUser(socket.id)
        console.log(user)
        if (user) {
            io.to(user.room).emit("message", generatemsg(`${user.username} left.`))

            io.to(user.room).emit("roomData", {
                room: user.room,
                users: getUserInRoom(user.room)
            })
        }
    })
})


server.listen(PORT, () => {
    console.log("server is up at port: " + PORT)
})
const mysql = require('mysql');

const pool  = mysql.createPool({
    connectionLimit : 100,
    host: "xxxx",
    port: 3306,
    user: "xxxx",
    password: "xxxx",
    database: 'xxxx',
    multipleStatements: true
});

pool.getConnection(function(err, connection) {
    if (err) throw err; // not connected!
    
    console.log('Connected from dbconfig.js');
});

module.exports.pool = pool;
const dbstuff = require('../../src/utils/dbconfig');

//Add New User
function addCurrentUserToDB(userTmp, roomTmp, colorTmp) {
    var sql = 'INSERT INTO pzs_info (username, roomname, usercolor) VALUES (?, ?, ?)';

    dbstuff.pool.query(sql, [userTmp, roomTmp, colorTmp], function (error, results, fields) {
        if (error) throw error;
        console.log('Added user' + userTmp); //result.changedRows
    });
}
因此,我对什么时候事情从server-side.js转移到client-side.js的理解开始变得模糊起来。Index.js是server-side.js,因为我能够使用一些变量=require('somemodule')

然后在我的utils目录中是我的数据库配置文件。为了共享mysql连接,我相信我需要创建一个池连接,这就是我在这里尝试做的

dbconfig.js

const path = require('path')
const http = require('http')
const express = require('express')
const socketio = require('socket.io')
const { generatemsg } = require('./utils/messages')
const { addUser, removeUser, getUser, getUserInRoom } = require('./utils/users')
const pool = require('./utils/dbconfig');
const db = require('../public/js/database');

const app = express()
const server = http.createServer(app)
const io = socketio(server)
const PORT = process.env.PORT || 3000

const publicdir = path.join(__dirname, '../public')

app.use(express.static(publicdir))

io.on("connection", (socket) => {
    console.log("new connection from socket.io")

    socket.on("join", ({ username, room }, cb) => {

        const { error, user } = addUser({ id: socket.id, username, room })

        if (error) {
            return cb(error)
        }
        
        socket.join(user.room)

        //generate random color
        const colorsArray = ["red", "green", "lime", "purple", "blue"]
        var arrayPos = Math.floor(Math.random() * colorsArray.length)
        var colorTmp = colorsArray[arrayPos]

        //Add New User to DB
        var userTmp = user.username
        var roomTmp = user.room
        
        db.addCurrentUserToDB(userTmp, roomTmp, colorTmp)

        io.to(user.room).emit("roomData", {
            room: user.room,
            users: getUserInRoom(user.room)
        })
        
        cb()
    })

    socket.on("sendMessage", (msg, cb) => {
        const user = getUser(socket.id)
        io.to(user.room).emit("message", generatemsg(user.username, msg))
        cb()
    })

    socket.on("disconnect", () => {
        const user = removeUser(socket.id)
        console.log(user)
        if (user) {
            io.to(user.room).emit("message", generatemsg(`${user.username} left.`))

            io.to(user.room).emit("roomData", {
                room: user.room,
                users: getUserInRoom(user.room)
            })
        }
    })
})


server.listen(PORT, () => {
    console.log("server is up at port: " + PORT)
})
const mysql = require('mysql');

const pool  = mysql.createPool({
    connectionLimit : 100,
    host: "xxxx",
    port: 3306,
    user: "xxxx",
    password: "xxxx",
    database: 'xxxx',
    multipleStatements: true
});

pool.getConnection(function(err, connection) {
    if (err) throw err; // not connected!
    
    console.log('Connected from dbconfig.js');
});

module.exports.pool = pool;
const dbstuff = require('../../src/utils/dbconfig');

//Add New User
function addCurrentUserToDB(userTmp, roomTmp, colorTmp) {
    var sql = 'INSERT INTO pzs_info (username, roomname, usercolor) VALUES (?, ?, ?)';

    dbstuff.pool.query(sql, [userTmp, roomTmp, colorTmp], function (error, results, fields) {
        if (error) throw error;
        console.log('Added user' + userTmp); //result.changedRows
    });
}
出于我不完全理解的原因,utils文件夹中的文件似乎仍然是服务器端js,这就是为什么我能够将它们包含在index.js文件中,并使用database.js文件中的函数(客户端)

在public/js文件夹中,我存储了我在整个应用程序中随机调用的所有数据库函数

Database.js(为简洁起见缩短)

database.js文件现在似乎是“客户端”js,因此,似乎无法访问mysql连接(因为它存储在我猜是服务器端的.js文件中),即使我在dbconfig.js文件中导出了它

根据我对上述代码的修改方式,我将得到以下错误:pool不是函数或pool是未定义的,在最新版本中,我一直在尝试这样做:

Database.js

const path = require('path')
const http = require('http')
const express = require('express')
const socketio = require('socket.io')
const { generatemsg } = require('./utils/messages')
const { addUser, removeUser, getUser, getUserInRoom } = require('./utils/users')
const pool = require('./utils/dbconfig');
const db = require('../public/js/database');

const app = express()
const server = http.createServer(app)
const io = socketio(server)
const PORT = process.env.PORT || 3000

const publicdir = path.join(__dirname, '../public')

app.use(express.static(publicdir))

io.on("connection", (socket) => {
    console.log("new connection from socket.io")

    socket.on("join", ({ username, room }, cb) => {

        const { error, user } = addUser({ id: socket.id, username, room })

        if (error) {
            return cb(error)
        }
        
        socket.join(user.room)

        //generate random color
        const colorsArray = ["red", "green", "lime", "purple", "blue"]
        var arrayPos = Math.floor(Math.random() * colorsArray.length)
        var colorTmp = colorsArray[arrayPos]

        //Add New User to DB
        var userTmp = user.username
        var roomTmp = user.room
        
        db.addCurrentUserToDB(userTmp, roomTmp, colorTmp)

        io.to(user.room).emit("roomData", {
            room: user.room,
            users: getUserInRoom(user.room)
        })
        
        cb()
    })

    socket.on("sendMessage", (msg, cb) => {
        const user = getUser(socket.id)
        io.to(user.room).emit("message", generatemsg(user.username, msg))
        cb()
    })

    socket.on("disconnect", () => {
        const user = removeUser(socket.id)
        console.log(user)
        if (user) {
            io.to(user.room).emit("message", generatemsg(`${user.username} left.`))

            io.to(user.room).emit("roomData", {
                room: user.room,
                users: getUserInRoom(user.room)
            })
        }
    })
})


server.listen(PORT, () => {
    console.log("server is up at port: " + PORT)
})
const mysql = require('mysql');

const pool  = mysql.createPool({
    connectionLimit : 100,
    host: "xxxx",
    port: 3306,
    user: "xxxx",
    password: "xxxx",
    database: 'xxxx',
    multipleStatements: true
});

pool.getConnection(function(err, connection) {
    if (err) throw err; // not connected!
    
    console.log('Connected from dbconfig.js');
});

module.exports.pool = pool;
const dbstuff = require('../../src/utils/dbconfig');

//Add New User
function addCurrentUserToDB(userTmp, roomTmp, colorTmp) {
    var sql = 'INSERT INTO pzs_info (username, roomname, usercolor) VALUES (?, ?, ?)';

    dbstuff.pool.query(sql, [userTmp, roomTmp, colorTmp], function (error, results, fields) {
        if (error) throw error;
        console.log('Added user' + userTmp); //result.changedRows
    });
}
我猜这是因为此时,database.js文件现在是client-side.js,不能使用require函数

但有趣的是,尽管它给了我console.log中database.js文件中的can't use require错误消息,但它实际上仍然将username/room/color写入数据库。算了吧

我的猜测是,关于节点如何在客户端/服务器端之间共享功能,有一些基本逻辑完全让我不知所措

更新: 我取得了一些进展,这要感谢这里的一个建议,即添加esm模块,它允许我将require与import语句混合/匹配

现在我可以从dbconfig.js文件(dbconfig是服务器,数据库是客户端)中拉入database.js文件中的连接,这很好

但是,我一直在尝试将database.js文件放入chat.js文件(两者都是客户端文件)

我已经尝试在chat.js文件的顶部添加导入语句

import { updateUserList } from './database.js';
然而,这会产生一个SyntaxError:导入声明可能只出现在模块错误的顶层

如果我还将type=“module”添加到我的chat.html文件中,如下所示:

<script src="/js/chat.js" type="module"></script>

然后我得到了几个不同的错误。chat.js文件出现404错误,由于不允许的mime类型错误等原因,文件被阻止

苏。。。我又开始转动轮子了。不知道为什么我不能将database.js文件包含在chat.html文件中,然后就到此为止


请告知。

Database.js文件中,dbstuff是您的池变量。使用dbstuff.query而不是dbstuff.pool.query。

@Murat指向mysql连接/响应的链接确实很有帮助,让我走上了正确的道路。这是另一个问题的链接

stackoverflow.com/a/67722081/13772090

然而,最终我还是使用了第三方服务,这对我来说比建立自己的基础设施要好得多。如果有人好奇的话,我会去的


谢谢大家

提示:使用ES6
import
而不是特定于节点的
require
,这会有所帮助。我在回答中给出了一个模块化的MySQL连接和查询处理程序函数。我相信这可能会解决你的问题@MuratColyaran,你的另一个答案在整个承诺的事情上有点让我不知所措,但是我想知道我是否尝试使用它的这一部分const{mySql}=require('./db.js');在我的database.js文件中,我将遇到相同的问题(require不被理解)。@Nick不,它不会那样工作。如果你把答案复制到一个文件中。您可以通过在任何地方调用该函数来运行任何查询。它非常干净。当然,您必须正确设置环境变量。@Nick您需要两边都有
db.js
。但重要的是,您需要为这两个数据库使用相同的DB配置。(主机、密码dbname等)。在建立数据库连接之后。只需调用函数并执行查询。我认为这个角色会尽你所能。由于此函数无法保持连接处于活动状态,因此您可以根据需要在服务器端和客户端运行查询。我尝试了此操作,刚得到一个dbstuff。查询不是函数错误。=/我想这是因为我不能在客户端js中使用require。