为何使用WebSocket时需通过http.createServer创建服务器?
Express实例与HTTP服务器实例的疑问解答
先看你给出的两段代码:
Socket.io 示例代码
const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const { Server } = require("socket.io"); const io = new Server(server);
ws 库示例代码
const express = require("express"); const app = express(); const WebSocket = require("ws"); const server = require("http").createServer(app); const wss = new WebSocket.Server({ server });
为什么要通过http.createServer(app)创建服务器?
你觉得app是可用的服务器,是因为Express封装了app.listen()方法,但本质上app只是一个请求处理函数——它符合Node.js HTTP服务器要求的(req, res) => {}签名,专门用来处理HTTP请求的路由和中间件逻辑,本身并没有底层网络监听的能力。
而Socket.io、ws这类WebSocket库,需要基于同一个HTTP服务器完成握手升级(WebSocket协议是从HTTP协议升级而来的),它们必须直接拿到Node.js原生的HTTP服务器实例,才能在上面同时挂载HTTP服务和WebSocket服务。只靠Express的app实例,根本没法完成WebSocket的挂载操作。
app和server两个实例的区别
app = express():这是Express的应用实例,核心管业务逻辑——比如定义路由、注册中间件、处理请求响应的具体逻辑。它就像一个“请求处理中心”,但自己不会去监听端口、处理底层的TCP连接。server = http.createServer(app):这是Node.js原生的HTTP服务器实例,负责底层的网络工作:监听指定端口、接收客户端的TCP连接、解析HTTP请求报文、发送HTTP响应。把app传进去,就是告诉这个服务器:所有收到的HTTP请求,都交给app来处理具体逻辑。
举个直白的例子,你平时用的app.listen(3000),内部其实就是帮你做了这两件事:创建HTTP服务器实例,然后调用它的listen方法。等价于:
const server = http.createServer(app); server.listen(3000);
内容的提问来源于stack exchange,提问作者b3rry
相关产品推荐
相关产品推荐

