才学习使用 nodejs 不久,在学习的过程当中产生了一个疑问。比如说用 node 实现一个功能: 从用户访问开始,每秒输出该用户的访问时间统计。比如我访问了就每秒输出 1 秒、2 秒、3 秒、4 秒、5 秒…… 但是我现在就实现了第一个用户访问的时候,执行这个函数。 后面的用户再访问,就会把函数重新执行了。 不知道怎么做可以统计用户各自的时间互不干扰。 用前端 js 实现这个功能,我知道怎么写。我就是想学习一下,这种问题用 node.js 该如何解决呢?
还有个问题, cluster 我也看了,各种 demo 里都是按照 CPU 数量来分配 worker 的。感觉这是做负载均衡之类的功能的吧?如果我用 cluster 来实现给每一个用户分配一个 worker 来解决上面的问题,是不是不对?
提前感谢各位花时间指点我~谢谢~
1
AlphaTr 2017-11-22 11:17:03 +08:00 1
cluster 不适合做,可以将计时器挂在 request 对象上执行,还有你是要输出到哪里?具体是做什么功能还是简单实现个 demo ?
|
3
AlphaTr 2017-11-22 11:23:25 +08:00 1
@inkWave
```javascript const http = require('http'); const port = 3000; const requestHandler = (request, response) => { let times = 0; console.log(request.url); const timer = setInterval(() => { times++; console.log("time: " + times); }, 1000); setTimeout(() => { clearInterval(timer); response.end('Hello Node.js Server!'); }, Math.random() * 10000); } const server = http.createServer(requestHandler); server.listen(port, (err) => { if (err) { return console.log('something bad happened', err); } console.log(`server is listening on ${port}`); }); ``` |
4
AlphaTr 2017-11-22 11:27:33 +08:00 1
回复里面不能用 markdown,补充楼上的 gist https://gist.github.com/alphatr/e002c09a4300c171dcb7259ad481e15e
|
5
inkWave OP |
6
AlphaTr 2017-11-22 11:32:59 +08:00 1
什么「多用户多进程」的问题?服务端为每个用户请求分配一个进程不靠谱,进程开销比较大,这么做是低效率的,给每个用户分配一个单独的进程是想解决什么问题?
|
9
EPr2hh6LADQWqRVH 2017-11-22 11:42:45 +08:00 1
你们这些楼上在搞什么飞机啊
楼主你要的是每个请求的等待时间,还是用户在站点上的留存时间啊 这两个是非常不一样的问题好嘛 你们楼上的代码统计的是每个请求的等待时间好嘛 |
11
inkWave OP @avastms 应该是这样:
A 用户访问一次,然后后端就开始输出距接到 A 请求过了 1 秒,2 秒,3 秒。。。 B 用户访问一次,后端开始输出距接到 B 请求过了 1 秒,2 秒,3 秒。。。 然后这几个输出互相不干扰。 怪我问题描述的不够清楚。 |
12
GooMS 2017-11-22 12:10:55 +08:00 via Android 1
在数据库记录用户上次请求时间不就行了,搞得这么复杂性能也低下。
|
14
rongyiran 2017-11-22 12:43:58 +08:00 1
如果是 APP 的话,可以用 UMENG 统计来解决.
web 不熟悉 |
15
Nitromethane 2017-11-22 13:15:40 +08:00 1
访问时间的设计思路请参考百度统计或腾讯统计;
更进一步分析可以研究下如何在页面里埋点; 如果需要更精确的统计,例如计费什么的,客户端和 server 要有心跳机制和 timeOut 才好吧; |
16
sdwill 2017-11-22 13:31:48 +08:00 1
我觉得可以用 socket 来实现。通过 socket 连接断开来判断。问题是看你怎么方便记录连上的时间,以及怎么处理 socket 意外断开的一些情况。
|
17
cccRaim 2017-11-22 13:31:58 +08:00 1
@inkWave
> 啊我不是在问这个实际问题怎么解决,这个问题是个例子,可能例子举得不够恰当。-_- 而我们回答的人更需要的是确切知道问题的所在,而不是将这个变成一个 X-Y 问题 我的理解就是前端轮询请求,这样就能知道页面是否开着,页面开着就表示用户还留存在页面上 如果想要更精确点,可以考虑 websocket,在每个客户端切断连接的时候处理时间停止计算逻辑 |
18
psnail 2017-11-22 15:50:40 +08:00
用户访问时长问题(会话时长)吧? 实际上不管服务端统计还是客户端统计都是存在误差的,因为你无法知道用户是否还在访问你的页面,按照上面的说明, 比如我打开一个 A 页面,然后新打开 tab 访问百度,过了一个小时再回来,难道用户就真的是访问 A 页面(或者留存在 A 页面)一个小时么?
|
19
qfdk 2017-11-22 15:55:41 +08:00 via iPhone
websocket 啊 用户连接有事件 断开也有事件 只要 ID 对了就结束计时就好了
|
20
nealv2ex 2017-11-22 15:57:40 +08:00
"用户各自的时间" 搜索关键字 "nodejs session cookie "
`http` 设计的是无状态的,每一次请求都是完全是独立的,为了区分同一个用户,就需要用到 `session` 和 `cookie` |
21
sodawy 2017-12-23 13:01:20 +08:00
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 发给后端。 |