我决定使用Deno来开发一个非常小的服务器,它将通过HTTP向客户端提供最小的页面,并继续通过WebSockets与客户端通信。
我还没有在网上找到任何关于使用Deno通过单个端口提供HTTP和WebSocket的材料(至少没有使用一些第三方库,我还没有检查过这些),所以我试图自己提出一个解决方案,但遇到了一个奇怪的问题。
以下是我目前为止的代码:
// Accept TCP connections over port 8080
for await (const connection of Deno.listen({ port: 8080 })) {
// Process all the arriving requests
for await (const requestEvent of Deno.serveHttp(connection)) {
// Check for the presence of an upgrade header
if (requestEvent.request.headers.get('upgrade') === 'websocket') {
// Provide a WebSocket connection
const { socket, response } = Deno.upgradeWebSocket(requestEvent.request)
socket.addEventListener('message', e => { console.log(e.data) })
requestEvent.respondWith(response)
} else {
// Otherwise just respond normally
requestEvent.respondWith(new Response('Hello!'))
}
}
}
字符串
当我运行这个时,我得到的奇怪行为是,我最初可以通过任何一种协议进行连接,但是一旦我与普通HTTP客户端连接,我就不能再创建新的WebSocket连接。相反的方式工作得很好。
1条答案
按热度按时间amrnrhlw1#
实际上,我已经设法弄清楚了这一点,同时尽量减少我在这里演示的可重复示例,但我认为我仍然会发布它,因为它也可能是其他人的有用资源。
所以,我的代码的问题是,除了WebSocket消息的处理之外,我几乎所有的东西都是同步的。这会导致循环停留在为单个HTTP连接服务,并阻止它处理其他连接及其请求。当然,如果我尝试从另一个设备连接,这也不起作用。
为了解决这个问题,我只需要做一个小小的调整,通过将每个连接 Package 在一个 * 立即调用的异步箭头函数 * 中,为每个连接提供自己的事件处理程序循环:
字符串
ps.:也许在监听器上循环使用
.accept().then(<connection handling code here>)
对某些人来说更易读,我想这有点主观。