node.js - 从服务器 `socket.io` 触发 (`node.js` 事件),而不是从客户端

标签 node.js sockets socket.io publish-subscribe

我正在尝试使用 node.js 制作游戏服务器, socket.io .

基本思想如下。

  • 初始化 socket.io服务器启动时的实例
  • 在全局范围内存储实例,以便 Controller 可以访问它
  • 当 API 调用时,我们会触发一些 socket.io Controller 中的事件或其他一些点

  • 这是我所做的实现......

    首先,在 server.js - 入口点
    let GlobalVars = require('./state/GlobalVars');
    const apiRouters = require('./router');
    
    ...
    
    app.use('/api', apiRouters);
    app.get('/', (req, res) => {
        res.sendFile(`${__dirname}/test/simpleClient.html`)
    });
    
    const httpServer = http.createServer(app);
    let socketIOInstance = socketIO(httpServer);
    socketIOInstance.on('connection', (socket) => {
        console.log('SOCKET.IO A USER CONNECTED');
        socket.on('create', (data) => {
            console.log('SOCKET.IO create called', socket);
            socket.join(data.room);
            socketIOInstance.emit('message', 'New people joined');
        });
        socket.on('join', (data) => {
            console.log('SOCKET.IO join called', data);
        })
        socket.emit('message', 'Hi');
    });
    GlobalVars.socketIO = socketIOInstance; 
    // Add to global, so the controllers can manage own actions like create, join ...
    httpServer.listen(port, () => {
        console.log(`Server Listening on the port ${port}`);
    })
    ...
    

    当我从客户端访问时,我可以看到 SOCKET.IO A USER CONNECTEDHi在浏览器控制台中。

    其次,在 api Controller 中。
    let GlobalVars = require('../state/GlobalVars');
    ...
    
    router.post('/create', (req, res) => {
      console.log('GenerateGameSokect');
      let game = new Game();
      let gameId = game.gameId;
      // console.log('Global vars ', GlobalVars.socketIO);
      GlobalVars.socketIO.emit('create', {
        room: gameId
      });
      res.json({
        result : 'SUCCESS',
        game : game
      })
    });
    

    我进口了GlobalVars其中包含 socketIO 实例。所以我所期望的是,socket create由语句 GlobalVars.socketIO.emit('create', Object) 触发的事件但在服务器日志中找不到消息。

    我不知道我错过了什么。

    我追求的最终形式是……
  • 当用户调用 create API 时,我创建了套接字连接和房间
  • API 会在 HTTP 协议(protocol)中调用,但在 API 中,服务器会发布一些事件。 - pubsub 喜欢。

  • 感谢您阅读我的问题 B. Here is full source code till now(bitbucket public)

    ================== 编辑====================

    我明白了(也许......)

    我想要的用户流程是......
  • 客户端调用 API
  • (在服务器中)检查 API 中的验证,如果有效则发送到 socket.io
  • 如果事件被接受,则向所有客户端发送新状态

  • 但是,创建 socket.io服务器中的连接对我来说看起来很奇怪,解决方案取决于客户端。

    新的用户流程我会改变
  • 客户端调用验证 API
  • 如果返回有效,则客户端发出 socket.io 事件。这次服务器只做验证,不发出 socket.io
  • 在套接字事件中,向所有其他用户发送新状态

  • ================== 编辑#2 ====================

    这是一种结论。看来我只是误解了套接字通信的概念。喜欢回答和回复说,SocketHTTP是完全不同的 channel ,没有办法将两者联系起来。 (至少,没有打开从 http 服务器到套接字的新连接)

    如有错误,请补充,谢谢

    最佳答案

    现在我明白你了。或者至少我认为!

    让我们这样说:套接字上有两个(不对称的)边,服务器和客户端。在我对你的帖子的评论中,我分别称之为“全局经理”和“套接字”。

    const server = require('socket.io')(yourHttpServer);
    // client is installed as well when `npm i socket.io`
    const client = require('socket.io-client')('http://localhost:' + yourServerPort);
    
    // `socket` is the server side of the socket
    server.on('connection', (socket) => {
      // this will be triggered by client sides emitting 'create'
      socket.on('create', (data) => {
        console.log('a client socket just fired a "create" event!');
      });
    });
    
    // this will be triggered by server side emitting 'create'
    client.on('create', (data) => {
      server.emit('create', {content: 'this will result in an infinite loop of "create" events!'});
    });
    

    在您的 /create路线,当你 GlobalVars.socketIO.emit('create', ...) ,服务器端套接字处理程序不会被触发,但是如果您有通过浏览器连接的客户端(或者,如我上面所示,如果您直接从服务器连接客户端套接字),那么这些将触发它们的 'create'听众,如果有的话。

    希望这可以帮助您走上正确的轨道!

    关于node.js - 从服务器 `socket.io` 触发 (`node.js` 事件),而不是从客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54511685/

    相关文章:

    c - 如何在 Linux 中重新绑定(bind) udp 套接字

    javascript - 使用socket.io保存网页状态

    javascript - 发送到套接字 IO socket.id

    javascript - Sequelize 播种机找不到模型的正确列名称

    node.js - 如何使用 nightwatch js 获取 Excel 中的行数和列数?

    java - 用 Java 6 编写 FTP 客户端

    c - 将 UDP 数据包发送到死服务器

    javascript - Bcrypt 比较密码时给出 false

    node.js - Node 服务器分段故障(核心转储),当收到websocket连接请求时

    javascript - 如何在没有express的情况下在nodejs中使用网络IP而不是localhost?