等待套接字连接建立更改页面路径时,直到将路由器数据发送给用户

如何解决等待套接字连接建立更改页面路径时,直到将路由器数据发送给用户

我需要先建立套接字连接,然后才能从路由向用户发送数据(否则不可能)。

app.js 文件中,我具有套接字连接逻辑:

app.use(function(req,res,next)
{
    req.sio = sio;
    next();
});

sio.on('connection',function(soc)
    {
        console.log('socket connected');
        soc.on('disconnect',function(reason)
        {
            console.log('socket disconnected');
        });
        // and more about socket connection here...
    });

index.js 文件中,我具有route.post逻辑:

router.post('/route1',function(req,next) // user is moved from index.js to route1.js if he fills the form
{
    var fromInput = req.body.form_name;
    console.log('DATA passed from INDEX.JS: ' + formInput);

    if ((formInput !== '') && (formInput !== null) && (formInput !== undefined))
    {
        function render()
        {
            //// first we render the page,so the javascript (with socket.io notes) can be read it and then the browser know that socket connection should be established
            return new Promise(function(resolve,reject)
            {
                resolve(res.render('route1'));
            });
        }

        // I need to pass some data AFTER the socked connection is established - cause I move to a different page path - using a **router.post** and cause of that socket connection is disconnected - so I need to wait till its usable again. For simplicity let suppose socket connection is established after 2 seconds (it is a simple check for req.soc.connected):

        var soc = false;

        setTimeout(function()
        {
            soc = true; // after 2 sec soc is true (connection is established)
        },2000);

        // Now I want to create an interval that will monitor IF socket connection is established every 100ms (so checking won't happen to often - it is not "resource hungry"). If socket connection is not ready the function should call it self (recursion) if the socket connection is established it (function) should fire a promise.

    var arr = [];
    arr.push(exe(100,data));

    function exe(delay,d)
    {
        d = data;
        return new Promise(function(resolve)
        {
            if (d === false)
            {
                setTimeout(function()
                {
                    console.log('wait another ' + delay + ' [ms] - ' + d);
                    return resolve(exe(delay,d));
                },delay);
            }
            else
            {
                console.log('socket connected!');
                return resolve(d);
            }
        });
    }
    render().then(function()
    {
        return Promise.all(arr).then(function(arr)
        {
            console.log(arr);
        });
    }).then(function()
    {
        console.log('ALL DONE!');
    });
    }
});

注释在代码中。如果不清楚,请告诉我。

@ jfriend00 1-是的, 2-是的, 3-我立即调用 render()-因此页面已加载,客户端建立了套接字连接,然后其余代码应执行并发送数据。


  1. 是的,我确实在表单中使用了POST。服务器和索引页之间可能存在套接字连接-这不是我可以创建的问题,但我不知道该怎么做。 “或者当浏览器呈现并处理POST时,可能会在对POST的响应中创建一个socket.io连接。”我正在尝试一个:)我在这个router.post中有数据,我想在套接字的帮助下发送-但是首先我需要建立连接。

  2. 据我了解,
  3. ...用户确实使用了表单,因此更改了路径(套接字连接已断开),然后进入router.post,我首先渲染了页面-这样浏览器就可以读取它的JS并建立套接字连接,但是您想说我的回答还没有结束吗?所以浏览器说-好的,您要我渲染页面,但是现在该怎么做-因为我们还没有完成?!

所以我将永远不会建立套接字连接,因为我没有正确响应?导致此原因的原因我将无法发送数据(router.post中的更高代码),未建立套接字连接,未正确响应吗?是因为我的测试向我展示了-是工作正常。

  1. 您是对的-代码现在应该可以使用。

  2. 直到套接字连接建立。

  3. 是的,很好。我将建立某种数据库-我猜想通过快速会话进行Redis。


因此,请再次逐步。 用户确实填写了表单,因此可以将其从index.js重定向到route1.js(因此,在填写表单之前是否存在套接字连接,这不会有所不同,否则不会导致连接丢失)。我们正在重定向他(router.post),所以我想我将立即呈现route1页面,以便浏览器可以读取其中的JS,并可以建立套接字连接(这需要时间-如果可能的话) 。因此,我等待要发送给用户的数据(例如,在router.post中……表单输入或其他内容),直到建立连接,然后在socket.io的帮助下将其发送给用户。

问题是更改页面(路径)时套接字io连接丢失。所以我认为(这可能是错误的原因,因为我是新手)然后我等待它建立,然后发送数据。我希望它确实有意义。

解决方法

此结构永远无法工作。这就是您要尝试执行的操作:

  1. Express服务器收到POST请求。
  2. 然后,您尝试等待socket.io连接出现,然后再处理POST并发送响应。
  3. 最后,当您认为找到了socket.io连接时,可以调用render()函数以“大概”发送响应。

在没有真正理解要执行的操作的情况下,当前代码有很多错误:

  1. POST请求来自Ajax调用或表单POST。没有socket.io连接与其中任何一个直接关联。在发送POST请求之前加载页面时,可能存在socket.io连接,或者在浏览器呈现和处理POST时,在对POST的响应中创建了socket.io连接。
  2. 即使在浏览器处理POST响应时创建了socket.io连接,您也要在发送响应之前尝试等待socket.io连接,这样您就在等待不会发生的事情直到您完成等待为止(本质上是一个死锁-A直到B完成才结束,但是B直到A完成才开始)。
  3. 此结构render().then(waitUntil(100,d))不正确。您必须传递.then()一个函数引用。您正在兑现承诺(返回值为waitUntil(...)的返回值形式)。不过,这是最少的问题,因为您尝试执行的整体结构是错误的。
  4. waitUntil()的整个实现过程令人困惑,我什至不知道它实际上正在等待什么。
  5. 这是一台服务器,可以处理来自许多客户端的许多连接。您不能只等待“下一个” socket.io连接,并假设该连接来自您刚刚请求的客户端。将socket.io连接与http请求关联的唯一方法是在两者(通常是cookie)中都使用一些识别特征,然后在http请求中,获得cookie并查询cookie以查看当前是否有一个cookie。与该Cookie匹配的socket.io连接。 express-socket.io-session可以帮助您。

不幸的是,您在这里没有描述您真正想要完成的工作,因此我无法为您提供一个好的解决方案。所有人,我真的可以在这里说,这个方案行不通。如果您想进一步解决实际问题,请编辑问题,以书面形式包含问题描述(而不是编码问题)。显示您想发生的事件的确切顺序,并说明您要完成的任务以及原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-