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

Sharing a mysql connection between client and server js files in node.js

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

我是 node.js 和 socket.io 的新手,所以请耐心等待,我正在尝试构建一个多聊天室应用程序的项目。

我卡在了尝试将我的代码分成“模块”的步骤。我的项目目录结构如下

我的 index.js 启动快速服务器并设置基本的 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)
})

所以我对什么时候从服务器-side.js 传输到客户端-side.js 的理解开始变得奇怪。 Index.js 是 server-side.js 因为我可以使用一些变量 = require('some module');

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

dbconfig.js

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;

由于我不完全理解的原因,utils 文件夹中的文件似乎仍然是服务器端 js,这就是为什么我能够将它们包含到 index.js 文件中并使用database.js 文件(客户端)中的函数。

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

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

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

    pool.getConnection(function(err, connection) {
        if (err) throw err; // not connected!
      
        // Use the connection
        connection.query(sql, [userTmp, roomTmp, colorTmp], (err, result, fields) => {
            if (err) throw err;
        
            console.log('Added user' + userTmp); //result.changedRows
            connection.release();
        });
    });
}

database.js 文件现在似乎是“客户端”js,因此似乎无法访问 mysql 连接(因为它存储在我猜是server-side.js 文件),即使我将其导出到 dbconfig.js 文件中。

根据我如何改变上面的代码,我会收到 pool is not a function 或 pool is undefined 等错误,在最新版本中我一直在这样试验:

Database.js

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 文件中的 require 错误消息,它实际上仍然写了用户名/房间/颜色到数据库。去图吧。

我的猜测是,节点如何在 client/server 之间共享功能的一些基本逻辑完全让我无法理解。

更新: 好吧,我取得了一些进展,这要归功于此处添加 esm 模块的建议,这使我能够 mix/match require with import 语句。

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

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

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

import { updateUserList } from './database.js';

但是这会产生语法错误:导入声明可能只出现在模块错误的顶层。

如果我也像这样将 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 连接/响应的 link 绝对有帮助,让我走上了正确的道路。这是另一个问题的link。

计算器。com/a/67722081/13772090

但是,最终我最终选择了使用第 3 方服务的 Pub/Sub 路线,这对我来说比尝试构建自己的基础设施要好得多。如果有人好奇,我和 Ably 一起去了。

谢谢大家!