【问题标题】:Socket.io connection event not fired on serverSocket.io 连接事件未在服务器上触发
【发布时间】:2016-07-14 14:19:32
【问题描述】:

我正在尝试使用 Node.js 和 Socket.io 构建一个命令行聊天室。

到目前为止,这是我的服务器端代码,我已经尝试了两种 http 初始化(使用 express,如官方网站的教程,没有它):

#app = require('express')()
#http = require('http').Server(app)
http = require('http').createServer()
io = require('socket.io')(http)


io.sockets.on 'connect', (socket) ->
  console.log 'a user connected'


http.listen 3000, () ->
  console.log 'listening on *:3000'

我以nodejs server.js 开头,“正在收听”正在显示。

如果我运行lsof -i tcp:3000,就会显示 server.js 进程。

但是,当我启动这个客户端代码时:

socket = require('socket.io-client')('localhost:3000', {})

socket.on 'connect', (socket) ->
  console.log "Connected"

不走运...当我运行 nodejs client.js 时,来自服务器和客户端的“连接”事件都不会被触发!

我的问题是: - 我究竟做错了什么? - 是否需要启动 HTTP 服务器才能使用它?套接字在传输层,对吧?所以理论上我不需要 HTTP 协议来交易消息。

【问题讨论】:

  • 那是 Coffeescript...

标签: node.js coffeescript socket.io


【解决方案1】:

如果这是一个服务器到服务器的连接,而您只是建立一个 socket.io 连接(而不是为常规 HTTP 连接设置它),那么这段代码显示了一个 socket.io 连接的简单方法:

监听 socket.io-only 服务器

// Load the library and initialize a server on port 3000
// This will create an underlying HTTP server, start it and bind socket.io to it
const io = require('socket.io')(3000);

// listen for incoming client connections and log connect and disconnect events
io.on('connection', function (socket) {
    console.log("socket.io connect: ", socket.id);

    socket.on('disconnect', function() {
        console.log("socket.io disconnect: ", socket.id);
    });
});

Node.js socket.io 客户端 - 连接到另一个 socket.io 服务器

// load the client-side library
const io = require('socket.io-client');
// connect to a server and port
const socket = io('http://localhost:3000');

// listen for successful connection to the server
socket.on('connect', function() {
    console.log("socket.io connection: ", socket.id);
});

此代码适用于我的计算机。我可以在同一主机上运行两个单独的 node.js 应用程序,它们可以相互通信,并且都可以看到连接和断开连接事件。

一些解释

socket.io 协议通过与 HTTP 服务器建立 HTTP 连接来启动。所以,只要你有一个 socket.io 连接,就会有一个 HTTP 服务器在某处监听。该 HTTP 连接最初发送时带有一些特殊的标头,这些标头向服务器指示这是“升级”到 webSocket 协议的请求,并且包括一些额外的安全信息。

这是 pretty great reference 关于如何最初建立 webSocket 连接的。它会一步一步地告诉你发生了什么。

一旦双方同意协议中的“升级”,则协议切换到webSocket(socket.io是在基础webSocket协议之上的附加协议层,但连接都建立在HTTP / webSocket 级别)。一旦同意升级,与最初传入的 HTTP 连接完全相同的 TCP 连接将重新用于 webSocket/socket.io 连接。

使用 socket.io 服务器端库,您可以自己创建 HTTP 服务器,然后将其传递给 socket.io,或者您可以让 socket.io 为您创建一个。如果您仅在此服务器上使用 socket.io 而不是使用 http 服务器共享常规 http 请求,那么您可以采用任何一种方式。上面的最小代码示例只是让 socket.io 透明地为您创建 http 服务器,然后 socket.io 绑定到它。如果您还处理来自 http 服务器的常规 Web 请求,那么您通常会先创建 http 服务器,然后将其传递给 socket.io,以便 socket.io 可以绑定到您已经拥有的 http 服务器。

然后,请记住 socket.io 正在使用 webSocket 传输。它只是 webSocket 传输之上的一些额外的数据包结构。这类似于同意通过 HTTP 连接发送 JSON。 HTTP 是主机传输和底层数据格式。然后双方同意将一些数据格式化为 JSON 格式并通过 HTTP 发送。 socket.io 消息格式以这种方式位于 webSocket 之上。

您的问题

是否需要启动HTTP服务器才能使用?

是的,HTTP 服务器必须存在于某个地方,因为所有 socket.io 连接都以对 HTTP 服务器的 HTTP 请求开始。

套接字在传输层,对吗?

初始连接协议栈是这样工作的:

TCP <- HTTP protocol

那么,协议升级后:

TCP <- webSocket <- socket.io

因此,在协议从 HTTP 升级到 webSocket 传输之后,您将拥有位于 TCP 之上的 webSocket 格式之上的 socket.io 数据包格式。

所以理论上我不需要 HTTP 协议来交易消息。

不,这是不正确的。所有连接最初都是使用 HTTP 建立的。一旦 webSocket 传输发生升级,就不再使用 HTTP。

【讨论】:

  • @Matheus208 - 这回答了你的问题吗?如果是这样,请检查答案左侧的绿色复选标记,以向社区表明您的问题现已得到解答,并通过遵循正确的程序为自己赢得一些声誉积分。如果这没有回答您的问题,那么请评论它仍然缺少什么,以便可以编辑答案以完成它。
猜你喜欢
  • 2021-12-10
  • 2020-09-25
  • 1970-01-01
  • 2016-07-17
  • 2017-01-18
  • 1970-01-01
  • 2014-01-08
  • 2014-01-30
相关资源
最近更新 更多