简体   繁体   English

NodeJS,SocketIO和Express逻辑上下文构建

[英]NodeJS, SocketIO and Express logic context build

I read a lot about Express / SocketIO and that's crazy how rarely you get some other example than a "Hello" transmitted directly from the app.js. 我读了很多关于Express / SocketIO的内容,这很疯狂你很少得到一些其他的例子而不是直接从app.js传输的“Hello”。 The problem is it doesn't work like that in the real world ... I'm actually desperate on a logic problem which seems far away from what the web give me, that's why I wanted to point this out, I'm sure asking will be the solution ! 问题是它在现实世界中不能像那样工作......我实际上对一个似乎远离网络给我的逻辑问题感到绝望,这就是为什么我想指出这一点,我敢肯定问是解决方案! :) :)

I'm refactoring my app (because there were many mistakes like using the global scope to put libs, etc.) ; 我正在重构我的应用程序(因为有许多错误,比如使用全局范围来放置库等); Let's say I've got a huge system based on SocketIO and NodeJS. 假设我有一个基于SocketIO和NodeJS的庞大系统。 There's a loader in the app.js which starts the socket system. app.js中有一个加载器启动套接字系统。

When someone join the app it require() another module : it initializes many socket.on() which are loaded dynamically and go to some /*_socket.js files in a folder. 当有人加入应用程序时,它需要()另一个模块:它初始化许多socket.on(),它们被动态加载并转到文件夹中的某些/*_socket.js文件。 Each function in those modules represent a socket listener, then it's way easier to call it from the front-end, might look like this : 这些模块中的每个函数都代表一个套接字监听器,然后从前端调用它更容易,可能如下所示:

  // Will call `user_socket.js` and method `try_to_signin(some params)`

  Queries.emit_socket('user.try_to_signin', {some params});

The system itself works really well. 系统本身运作良好。 But there's a catch : the module that will load all those files which understand what the front-end has sent also transmit libraries linked with req/res (sessions, cookies, others...) and must do it, because the called methods are the core of the app and very often need those libraries. 但是有一个问题:将加载所有那些了解前端发送的文件的模块还传输与req / res链接的库(会话,cookie,其他......)并且必须这样做,因为被调用的方法是应用程序的核心,通常需要这些库。

In the previous example we obviously need to check if the user isn't already logged-in. 在前面的示例中,我们显然需要检查用户是否尚未登录。

  // The *_socket.js file looks like this :

  var $h = require(__ROOT__ + '/api/helpers');

  module.exports = function($s, $w) {

    var user_process = require(__ROOT__ + '/api/processes/user_process')($s, $w);

      return {

        my_method_called: function(reference, params, callback) {

          // Stuff using $s, $w, etc.

        }

  }

  // And it's called this way :

  // $s = services (a big object)
  // $w = workers (a big object depending on $s)
  // They are linked with the req/res from the page when they are instantiated

  controller_instance = require('../sockets/'+ controller_name +'_socket')($s, $w);

  // After some processes ...

  socket_io.on(socket_listener, function (datas, callback) {

       // Will call the correct function, etc.

       $w.queries.handle_socket($w, controller_name, method_name, datas);

  });

The good news : basically, it works. 好消息:基本上,它有效。

The bad news : every time I refresh the page, the listeners double themselves because they are in a loop called on page load. 坏消息:每次刷新页面时, 监听器都会自行加倍,因为它们处于页面加载的循环中。

Below, this should have been one line : 下面,这应该是一行:

在此输入图像描述

So I should put all the socket.on('connection'...) stuff outside the page loading, which means when the server starts ... Yes, but I also need the req/res datas to be able to load the libraries, which I get only when the page is loaded ! 所以我应该将所有socket.on('connection'...)东西放在页面加载之外,这意味着当服务器启动时...是的,但我还需要req / res数据才能加载库,只有在页面加载时才能获得!

It's a programing logic problem, I know I did something wrong but I don't know where to go now, I got this big system which "basically" works but there's like a paradox on the way I did it and I can't figure out how to resolve this ... It's been a couple of hours I'm stuck. 这是一个编程逻辑问题,我知道我做错了什么但我不知道现在去哪里,我得到了这个“基本上”工作的大系统但是我做的方式就像一个悖论而我无法想象如何解决这个问题......我被困了几个小时。

How can I refacto to let the possibility to get the current libraries depending on req/res within a socket.on() call ? 我如何重构以允许根据socket.on()调用中的req / res获取当前库的可能性? Is there a trick ? 有诀窍吗? Should I think about changing completely the way I did it ? 我是否应该考虑完全改变我的做法?

Also, is there another way to do what I want to do ? 还有,还有另一种方法可以做我想做的事吗?

Thank you everyone ! 谢谢大家 !

NOTE : If I didn't explain well or if you want more code, just tell me :) 注意:如果我没有解释好或者你想要更多代码,请告诉我:)

EDIT - SOLUTION : As seen above we can use sockets.once(); 编辑 - 解决方案:如上所示,我们可以使用sockets.once(); instead of sockets.on(), or there's also the sockets.removeAllListeners() solution which is less clean. 而不是sockets.on(),或者还有sockets.removeAllListeners()解决方案,不太干净。

Try As Below. 试试如下。

io.sockets.once('connection', function(socket) {
  io.sockets.emit('new-data', {
    channel: 'stdout',
    value: data
 }); 
});

Use once instead of on. 使用一次而不是打开。

This problem is similar as given in the following link. 此问题与以下链接中给出的类似。

https://stackoverflow.com/questions/25601064/multiple-socket-io-connections-on-page-refresh/25601075#25601075 https://stackoverflow.com/questions/25601064/multiple-socket-io-connections-on-page-refresh/25601075#25601075

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM