Issue
I made a web server that serves as a client-side using socket.io-client and express (because I have to use this form in other project).
It emits the string posted and when receiving ‘boom’ emit from io server it responds by sending the string served.
Posting ‘heat_bomb’ works well for the first time, but when I try second time ‘[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client’ occurs at res.send(data) in socket.on().
Is there a way to refresh whenever post request is generated, so that each request uses independent response?
app.ts
import express from 'express'
import {io} from 'socket.io-client'
import bodyParser from 'body-parser'
const app=express()
const PORT=8080
const socket=io(`http://localhost:2002`, {
query:{
hello:"merhaba"
}
})
app.use(bodyParser.urlencoded({extended:false}))
app.get('/', (req, res)=>{
res.sendFile(__dirname+`/index.html`)
})
app.post('/heat_bomb', (req, res)=>{
socket.emit('heat_bomb', req.body.elem)
socket.on('boom', (data)=>{
res.send(data)
})
})
app.listen(PORT, ()=>{
console.log(`Server Running: ${PORT}`)
})
index.html
$('#heat_button').click(function(){
console.log('heating bomb')
$.post('/heat_bomb', {elem: $('#input_number').val()},(data, status)=>{
console.log(data)
console.log('heated')
})
})
Solution
Your /heat_bomb
middleware registers a new boom
handler for every request on the same globally defined socket
. Although your code snippet does not show how the heat_bomb
and boom
events are connected, I assume that the emit('boom')
during the second request re-triggers the heat_bomb
handler that was registered during the first request, leading to another res.send
for the res
from the first request, which is already completed. This leads to the observed error message.
socket.once('boom')
alone will not solve this reliably: if one heat_bomb
event can overtake another, the data
from the first can wrongly be "paired" with the res
from the second. The res
needs to be a second argument of your events, something like this:
socket.emit('heat_bomb', req.body.elem, res);
socket.once('boom', function(data, res) {
res.send(data);
});
Answered By – Heiko Theißen
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0