使用 fetch api 时使用 socket.io 广播消息

Broadcast messages with socket.io while using fetch api

我正在使用 fetch api 到 post 并检索用户数据,效果很好,但我还想将 sioket.io 实现到 fetch 中以发出和广播我选择的数据来自 mysql 数据库。

服务器端:

var server = require('http').createServer(app);
var io = require('socket.io')(server);


app.use(function(request, result, next) {
    result.setHeader("Access-Control-Allow-Origin", "*");
    next();
})



dotenv.config({ path: './.env' });


var sqlDatabase = mysql.createConnection({
    host: process.env.DATABASE_HOST,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE,

});


app.set('view engine', 'hbs');

app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(cookieParser('key cat'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator());
app.use(cors());


const publicDirectory = path.join(__dirname, './public')
app.use(express.static(publicDirectory));

var options = {
    host: process.env.DATABASE_HOST,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE,

};

var sessionStore = new MySQLStore(options);


app.use(session({
    secret: 'key cat',
    resave: false,
    saveUninitialized: false,
    store: sessionStore,
    cookie: {
        httpOnly: true,
        secure: false,
        maxAge: 60000
    }
}));

app.use(passport.initialize());
app.use(passport.session());




sqlDatabase.connect((err) => {
    if (err) {
        console.log(err);
    } else {
        console.log('mysql is connected')
    }
});

io.on('connection', (socket) => {
    console.log('socket connect successful');
    socket.on('new_message', function(results) {
        console.log('Client says', results);


    })


    app.get("/get_messages", function(request, result) {
        sqlDatabase.query("SELECT users.username, comments.comments, comments.date FROM users INNER JOIN comments ON users.user_id=comments.user_id",
            function(error, results) {
                io.emit('new_message', JSON.stringify(results))

            });
    });
});




app.use((req, res, next) => {
    res.locals.isAuthenticated = req.isAuthenticated();
    next();
});

我认为问题出在哪里:

io.on('connection', (socket) => {
    console.log('socket connect successful');
    socket.on('new_message', function(results) {
        console.log('Client says', results);


    })


    app.get("/get_messages", function(request, result) {
        sqlDatabase.query("SELECT users.username, comments.comments, comments.date FROM users INNER JOIN comments ON users.user_id=comments.user_id",
            function(error, results) {
                io.emit('new_message', JSON.stringify(results))

            });
    });
});

如果我使用

result.end(JSON.stringify(results));

结果很好,除了我还想发射和广播数据,这就是我使用 sioket.io.

的原因

客户端:

function loadcomments() {
    fetch('http://localhost:5502' + '/get_messages')

    .then(response => {
            if (response.ok) {
                console.log('success')
                console.log(response);
            } else {
                console.log('failure')
            }
            return response.json();
        })
        .then(function(data) {

                output.innerHTML = '';

                data.forEach(function(user) {

                    io.emit("new_message", comments.value)


                    io.on("new_message", function(results) {
                        console.log("Server says", results);

                        var newUser = document.createElement("div");
                        var newName = document.createElement("h5");
                        var newDate = document.createElement("h5");
                        var newMessage = document.createElement("h6");

                        var display_username = document.createTextNode(JSON.stringify(user.username));
                        var display_date = document.createTextNode(JSON.stringify(user.date));
                        var display_comments = document.createTextNode(JSON.stringify(user.comments));


                        newName.appendChild(display_username);
                        newDate.appendChild(display_date);
                        newMessage.appendChild(display_comments);

                        newUser.appendChild(newName);
                        newUser.appendChild(newDate);
                        newUser.appendChild(newMessage);
                        output.appendChild(newUser);

                        console.log(data);

                    }).catch(function(error) {
                        console.log(error)

一直在兜圈子。我查看了类似的问题,但我知道我在做某事,只是不知道是什么。

顺便说一句,我是菜鸟。任何帮助表示赞赏。提前谢谢你。

答案已更改: 进行一些调整后,我得到的唯一输出是第一个数据条目。此外,当我提交评论时,会返回第一个数据条目的多个响应: [![在此处输入图片描述][1]][1]

这是我更改代码的地方:

 .then(function(data) {

            output.innerHTML = '';
            data.forEach(function(user) {

                io.emit("new_message", comments.value)

                io.on("new_message", function(data) {
                    console.log("Server says", data);

                    var newUser = document.createElement("div");
                    var newName = document.createElement("h5");
                    var newDate = document.createElement("h5");
                    var newMessage = document.createElement("h6");

                    var display_username = document.createTextNode(JSON.stringify(user.username));
                    var display_date = document.createTextNode(JSON.stringify(user.date));
                    var display_comments = document.createTextNode(JSON.stringify(user.comments));
    ```


  [1]: https://i.stack.imgur.com/i0bsd.jpg

服务器端:

io.on('connection', (socket) => {
    console.log('socket connect successful');

    socket.on('new_message', function(message) {
        console.log('Client says', message);
        io.emit('new_message', message)


    })
})


app.get("/get_messages", function(request, result) {
    sqlDatabase.query("SELECT users.username, comments.comments, comments.date FROM users INNER JOIN comments ON users.user_id=comments.user_id",
        function(error, results) {
            result.end(JSON.stringify(results));
        });
});

客户端

function loadcomments() {
    fetch('http://localhost:5502' + '/get_messages')

    .then(response => {
            if (response.ok) {
                console.log('success')
                console.log(response);
            } else {
                console.log('failure')
            }
            return response.json();
        })
        .then(function(data) {
            io.emit("new_message", data)
            io.on("new_message", function(data) {
                console.log("Server says", data);
                output.innerHTML = '';
                data.forEach(function(user) {

                    var newUser = document.createElement("div");
                    var newName = document.createElement("h5");
                    var newDate = document.createElement("h5");
                    var newMessage = document.createElement("h6");

                    var display_username = document.createTextNode(JSON.stringify(user.username));
                    var display_date = document.createTextNode(JSON.stringify(user.date));
                    var display_comments = document.createTextNode(JSON.stringify(user.comments));


                    newName.appendChild(display_username);
                    newDate.appendChild(display_date);
                    newMessage.appendChild(display_comments);

                    newUser.appendChild(newName);
                    newUser.appendChild(newDate);
                    newUser.appendChild(newMessage);
                    output.appendChild(newUser);

请注意我如何组织这部分:

  .then(function(data) {
            
            io.emit("new_message", data)
            io.on("new_message", function(data) {
                
                console.log("Server says", data);
                output.innerHTML = '';
                data.forEach(function(user) {

                    var newUser = document.createElement("div");

我遇到的问题是我一直在数据库中获取第一个条目作为输出并重复。放置这个

io.emit("new_message", data);
io.on("new_message", function(data) {

在此之上:

output.innerHTML = '';
data.forEach(function(user) {

解决了问题。