Nodejs 如何用 node.js 统计用户访问时间

发布于 1周前 作者 htzhanglong 来自 nodejs/Nestjs

Nodejs 如何用 node.js 统计用户访问时间

才学习使用 nodejs 不久,在学习的过程当中产生了一个疑问。比如说用 node 实现一个功能: 从用户访问开始,每秒输出该用户的访问时间统计。比如我访问了就每秒输出 1 秒、2 秒、3 秒、4 秒、5 秒…… 但是我现在就实现了第一个用户访问的时候,执行这个函数。 后面的用户再访问,就会把函数重新执行了。 不知道怎么做可以统计用户各自的时间互不干扰。 用前端 js 实现这个功能,我知道怎么写。我就是想学习一下,这种问题用 node.js 该如何解决呢?

还有个问题, cluster 我也看了,各种 demo 里都是按照 CPU 数量来分配 worker 的。感觉这是做负载均衡之类的功能的吧?如果我用 cluster 来实现给每一个用户分配一个 worker 来解决上面的问题,是不是不对?

提前感谢各位花时间指点我~谢谢~


22 回复

cluster 不适合做,可以将计时器挂在 request 对象上执行,还有你是要输出到哪里?具体是做什么功能还是简单实现个 demo ?


就输出在后台可以看到就可以了,简单 demo。
关键的是想解决给每一个用户分配一个进程的问题。



javascript<br>const http = require('http');<br>const port = 3000;<br><br>const requestHandler = (request, response) =&gt; {<br> let times = 0;<br> console.log(request.url);<br> const timer = setInterval(() =&gt; {<br> times++;<br> console.log("time: " + times);<br> }, 1000);<br> <br> setTimeout(() =&gt; {<br> clearInterval(timer);<br> response.end('Hello Node.js Server!');<br> }, Math.random() * 10000);<br>}<br><br>const server = http.createServer(requestHandler);<br><br>server.listen(port, (err) =&gt; {<br> if (err) {<br> return console.log('something bad happened', err);<br> }<br><br> console.log(`server is listening on ${port}`);<br>});<br>

您说的这个我看懂了。感谢~

除了这种方法,还有什么方法或者思路呢?

因为我主要是想了解如何用 node.js 解决多用户多进程的问题。

什么「多用户多进程」的问题?服务端为每个用户请求分配一个进程不靠谱,进程开销比较大,这么做是低效率的,给每个用户分配一个单独的进程是想解决什么问题?

就是给每个访问者跑不同的程序,互不干扰。大概是这个意思。

修正一下,应该是不同用户跑同样的程序,但是不断得到各自不同的输出结果。

你们这些楼上在搞什么飞机啊
楼主你要的是每个请求的等待时间,还是用户在站点上的留存时间啊
这两个是非常不一样的问题好嘛
你们楼上的代码统计的是每个请求的等待时间好嘛

留存时间。

应该是这样:
A 用户访问一次,然后后端就开始输出距接到 A 请求过了 1 秒,2 秒,3 秒。。。
B 用户访问一次,后端开始输出距接到 B 请求过了 1 秒,2 秒,3 秒。。。
然后这几个输出互相不干扰。
怪我问题描述的不够清楚。

在数据库记录用户上次请求时间不就行了,搞得这么复杂性能也低下。

啊我不是在问这个实际问题怎么解决,这个问题是个例子,可能例子举得不够恰当。-_-

如果是 APP 的话,可以用 UMENG 统计来解决.
web 不熟悉

访问时间的设计思路请参考百度统计或腾讯统计;
更进一步分析可以研究下如何在页面里埋点;

如果需要更精确的统计,例如计费什么的,客户端和 server 要有心跳机制和 timeOut 才好吧;

我觉得可以用 socket 来实现。通过 socket 连接断开来判断。问题是看你怎么方便记录连上的时间,以及怎么处理 socket 意外断开的一些情况。


> 啊我不是在问这个实际问题怎么解决,这个问题是个例子,可能例子举得不够恰当。-_-
而我们回答的人更需要的是确切知道问题的所在,而不是将这个变成一个 X-Y 问题

我的理解就是前端轮询请求,这样就能知道页面是否开着,页面开着就表示用户还留存在页面上
如果想要更精确点,可以考虑 websocket,在每个客户端切断连接的时候处理时间停止计算逻辑

用户访问时长问题(会话时长)吧? 实际上不管服务端统计还是客户端统计都是存在误差的,因为你无法知道用户是否还在访问你的页面,按照上面的说明, 比如我打开一个 A 页面,然后新打开 tab 访问百度,过了一个小时再回来,难道用户就真的是访问 A 页面(或者留存在 A 页面)一个小时么?

websocket 啊 用户连接有事件 断开也有事件 只要 ID 对了就结束计时就好了

“用户各自的时间” 搜索关键字 "nodejs session cookie "
http 设计的是无状态的,每一次请求都是完全是独立的,为了区分同一个用户,就需要用到 sessioncookie

1、node 是如何做到请求之间变量互不干扰的? node 默认时是单进程单线程在处理请求(我们先不谈 cluster 和 threadpool ),单线程内的 eventloop 中有个 i/o callback 的 queue,每个请求来了之后就会进这个 q,eventloop 处理到 i/o callback 这个阶段时,就会从这个 queue 里取请求依次运行其 handler,由于每个请求都在自己的 function 上下文中(运行栈),变量是互相隔离的。

2、如何实现,用户来了之后,一直在服务器端打印? 问题 1 中说了,每个请求 function 运行时互相隔离的,请求结束了,这个 function 堆栈中的变量就访问不到了。但楼主想请求结束了,还一直打印(直到另一个请求来了,告诉我停止打印)。你可以用 setInterval 不停打印,然后把这个 timer 句柄保存在一个进程级全局的变量(process\global)或存储(file\db)中,收到用户走了的请求后,根据用户 id,找到这个 timer 句柄(其实就是一个整数),clearInterval 掉就可以了。

3、如何设计前后端的交互? 前端想清楚如何判定啥时候用户来了、走了,如何标识同一个用户,并把这些信息通过 http 或 ws 发给后端。

在 Node.js 中统计用户访问时间可以通过记录请求到达和离开的时间戳来实现。下面是一个简单的示例,展示如何使用 Express 框架来统计用户访问时间。

首先,确保你已经安装了 Express 框架:

npm install express

然后,创建一个 server.js 文件,并添加以下代码:

const express = require('express');
const app = express();
const port = 3000;

app.use(express.json());

app.get('/', (req, res) => {
    const startTime = Date.now();

    // 模拟一些处理时间
    setTimeout(() => {
        const endTime = Date.now();
        const duration = endTime - startTime;

        res.json({
            message: 'Hello, World!',
            duration: `${duration}ms`
        });
    }, 1000); // 这里设置为1秒,可以根据实际情况调整
});

app.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`);
});

在这个示例中,我们创建了一个简单的 Express 应用,并在根路径 / 上添加了一个 GET 路由。当请求到达时,记录当前时间戳 startTime,然后模拟一些处理时间(使用 setTimeout 延迟 1 秒)。处理完成后,记录结束时间戳 endTime,并计算访问时间 duration,最后将结果作为 JSON 响应返回。

运行这个服务器,访问 http://localhost:3000/,你应该会在响应中看到访问时间。这个示例可以根据实际需求进行扩展,比如记录日志、统计所有请求的平均访问时间等。

回到顶部