NodeJS,Express与Socket.io交互

时间:2018-04-25 14:12:42

标签: javascript node.js express websocket socket.io

目前正在使用同时使用express.jsSocket.io的Node.JS后端。应用程序的基础如下所示:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

因此,如果我理解正确,express.js会处理所有HTTP/HTTPS请求,而Socket.io会处理有关websockets的所有交互。所以这些是完全分离的2个实体。应用程序启动后,express部分正在侦听http个请求,而socket.io部分正在侦听websocket事件或连接(连接已完成HTTP,websocket使用HTTP标头握手)。由于express实例和socket.io实例共享相同的HTTP服务器,因此它们可以使用相同的TCP连接。

问题:

  1. 我上面描述的当前理解是否正确?
  2. 这两个实体可以相互影响,如果是这样的话,会以什么方式进行互动?

1 个答案:

答案 0 :(得分:1)

要了解它的工作原理,您必须了解socket.io连接的工作原理,然后您才能看到它与您的http服务器的关系。

  1. 默认的socket.io连接以一对http请求开始。这就是socket.io客户端与服务器协商以确定两者可以支持的确切方式。这些http请求将发送到您的node.js Web服务器(与Express用于Express的服务器相同)。 socket.io插入的请求处理程序拦截这些请求并处理它们,因此它们不会发送到Express路由。
  2. 在上述几个http请求之后,如果双方同意可以将webSocket连接作为正在进行的socket.io连接的基本传输,则socket.io客户端会向服务器发送特殊的http请求有一些自定义标题。
  3. http服务器(同样是你用于Express的那个)接收到这个特殊的http请求,socket.io服务器代码再次拦截该请求并处理它。在这种情况下,它通过"升级"来响应这个特殊的http请求。到webSocket协议和作为http请求启动的套接字转换为webSocket协议,并成为一个只能说webSocket协议的长期套接字。
  4. 此时,http Web服务器不再参与进一步的通信。作为http请求启动的套接字已经传递给socket.io服务器代码,该套接字现在正在说webSocket协议。此时,客户端或服务器都可以通过该套接字发送消息,并且它们将由另一端的相应代码接收。
  5. 现在,socket.io实际上在webSocket上使用了一个层。虽然底层数据包是为webSocket协议格式化的,但socket.io在webSocket上添加了自己的应用程序层,这意味着你必须在两端都有socket.io代码才能使用(socket.io客户端可以&#39) ;与普通的webSocket服务器通信,反之亦然。)
  6.   

    因此,如果我理解正确,express.js会处理所有HTTP / HTTPS请求,而Socket.io会处理有关websockets的所有交互。

    排序。 http服务器(Express的基础)处理所有传入的http请求。这包括将通过Express路由的普通http请求,但它还包括与打开和建立socket.io连接相关的http请求。这些特殊请求由socket.io插入的http服务器请求处理程序处理,而不是传递给Express处理的行。

      

    所以这些是完全分开的2个实体。

    有一个http服务器,然后是一些请求处理程序,它们决定Express是否应该处理请求,或者socket.io是否应该处理请求。有一次,请求已经传递给另一个请求,它们几乎是分开的。

    但是,有一些点可以交叉。例如,如果您使用Express的会话管理器设置会话cookie或设置cookie的任何其他类型的代码,那么这些cookie也可用于socket.io连接。因此,使用正确的支持代码,socket.io连接可以访问由Express中间件或请求处理程序创建的会话对象(或其他cookie)。请记住,socket.io连接以http请求开头,因此浏览器通常会发送带有http请求的任何cookie也会出现在socket.io请求中。

      

    应用程序启动后,express部分正在侦听http请求,而socket.io部分正在侦听websocket事件或连接(使用HTTP完成连接,使用HTTP头进行websocket握手)。

    正如我上面所说,http服务器正在侦听传入的http请求,socket.io和Express都有请求处理程序查看这些传入请求并决定它们是否应该参与处理该请求。一些传入的请求被定向到socket.io服务器代码,一些被定向到快速路由处理程序。

      

    因为express实例和socket.io实例共享同一个HTTP服务器,所以它们可以使用相同的TCP连接。

    他们并不真正共享TCP连接。有一个共享的http服务器可以侦听传入的http请求。然后将这些请求路由到socket.io代码或表达代码,以便根据请求中的数据进行进一步处理。如果它是一个socket.io请求来启动socket.io连接,那么该TCP套接字将被升级"到webSocket协议,只有socket.io服务器代码处理那个TCP套接字。如果它不是socket.io请求,则将http请求传递给Express代码,并根据定义的中间件和路由决定如何处理它。

      

    我上面描述的当前理解是否正确?

    部分正确,部分不正确。上面有很多细节。

      

    这两个实体可以互相交互,如果是这样,会以什么方式进行交互?

    他们共享http服务器。他们共享cookie。

    使用正确的服务器端代码,可以使用http请求(通常是来自已加载的网页的Ajax调用)进入Express,并且该请求处理程序可以将数据发送到该特定客户端它对应的socket.io连接。使用某种cookie客户端标识符,可以将现有的socket.io连接与传入的http请求相关联。

    我应该补充一点,我在上面描述的是当你对从加载网页的同一主机和端口建立socket.io连接时的工作方式。这不是必需的。您可以使用一个http服务器来加载所有网页和Web资源,另一个http服务器(在不同的主机/端口组合上)可以记录传入的socket.io请求。在这种情况下,事物的明确方面实际上与socket.io方面无关。他们实际上是不同的服务器,可能不会共享cookie等...