在 node.js 中的客户端和服务器 js 文件之间共享 mysql 连接
Posted
技术标签:
【中文标题】在 node.js 中的客户端和服务器 js 文件之间共享 mysql 连接【英文标题】:Sharing a mysql connection between client and server js files in node.js 【发布时间】:2021-08-16 06:01:57 【问题描述】:我在这里看到过类似的问题,但没有一个完全像这样,所以我希望我不会重复已经问过的问题。
我对 node.js 和 socket.io 还很陌生,所以请多多包涵,我正在尝试构建一个多聊天室应用程序的项目。
我被困在我试图将我的代码分成“模块”的一步。我的项目目录结构如下。
我的 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)
)
所以我对事情何时从 server-side.js 转移到 client-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 文件中。
根据我如何改变上述代码,我会得到错误,从池不是函数或池未定义,在我一直在尝试的最新版本中,如下所示:
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 错误消息,它实际上仍然将用户名/房间/颜色写入数据库。去图吧。
我的猜测是节点如何在客户端/服务器端之间共享功能的一些基本逻辑让我完全无法理解。
更新: 好吧,我已经取得了一些进展,这要归功于这里添加 esm 模块的建议,这允许我将 require 与 import 语句混合/匹配。
所以我现在可以从 dbconfig.js 文件中拉入 database.js 文件中的连接(dbconfig 是服务器,数据库是客户端),这很好。
但是我一直在尝试将 database.js 文件放入 chat.js 文件中(它们都是客户端)。
我尝试在 chat.js 文件的顶部添加一个 import 语句
import updateUserList from './database.js';
但是这会产生一个语法错误:导入声明可能只出现在模块错误的顶层。
如果我也像这样将 type="module" 添加到我的 chat.html 文件中:
<script src="/js/chat.js" type="module"></script>
然后我得到几个不同的错误。 chat.js 文件出现 404 错误,文件因不允许的 mime 类型错误等而被阻止。
Soo...我又在旋转我的***了。不知道为什么我不能只在我的 chat.html 文件中包含 database.js 文件并收工。
请指教。
【问题讨论】:
提示:可以帮助的一件事是使用 ES6import
而不是特定于节点的 require
。
我在回答中给出了一个模块化的 MySQL 连接和查询处理函数。我相信这可能会解决你的问题。 ***.com/a/67722081/13772090
@MuratColyaran,你的另一个答案对我来说有点过分了,但我想知道我是否尝试使用它的这一部分 const mySql = require('./ db.js');在我的 database.js 文件中,我将遇到同样的问题(require 不被理解)。
@Nick 不,它不会那样工作。如果您将该答案原样复制到文件中。您可以通过在任何地方调用该函数来运行您想要的任何查询。它工作得非常干净。当然,你必须给环境变量正确。
@Nick 双方都需要db.js
。但重要的是您需要为两者使用相同的数据库配置。 (主机、密码 dbname 等)。建立数据库连接后。只需调用该函数并执行查询。我认为会尽力而为的部分。由于此功能不会保持连接处于活动状态,因此您可以根据需要在服务器端和客户端运行查询。
【参考方案1】:
在 Database.js 文件中,dbstuff 是您的池变量。使用 dbstuff.query 而不是 dbstuff.pool.query。
【讨论】:
我试过了,我刚得到一个 dbstuff.query is not a function 错误。 =/我认为是因为我不能在客户端js中使用require。【参考方案2】:@Murat 的 mysql 连接/响应链接绝对有帮助,让我走上了正确的道路。这是另一个问题的链接。
***.com/a/67722081/13772090
但是,最终我最终选择了使用 3rd 方服务的 Pub / Sub 路线,这对我来说比尝试构建自己的基础架构要好得多。如果有人好奇,我会选择 Ably。
谢谢大家!
【讨论】:
以上是关于在 node.js 中的客户端和服务器 js 文件之间共享 mysql 连接的主要内容,如果未能解决你的问题,请参考以下文章
将存储在 S3 存储桶中的文件直接下载到 React 客户端,而不是通过 Node.js 服务器
如何递归遍历目录,通过 node.js 中的套接字发送所有文件名?
受祝福的服务器(Node.js)通过 websocket 到浏览器中的 Xterm.js 客户端