totorojs / browsers

A simple and stable browser driver.
19 stars 5 forks source link

浏览器状态监控的处理 #26

Closed leoner closed 11 years ago

leoner commented 11 years ago

相关背景和讨论参看 #14

基本思路

  1. browsers-launcher 启动一个监听服务
  2. 打开 totoro 的 capture 页面时,这个页面会加载一个 browsers-launcher 的一个 js
  3. 这个加载的 js 会定时和 browsers-launcher 的监听服务进行通信,并会把当前 capture的 url 中和浏览器关联的 id 发送到监听服务
  4. 这个监听服务会保存接收id 的状态,然后定时扫描目前已经开启的浏览器中的 id 是否保持着正常通信。
  5. 如果已经开启的浏览器中的 id 长时间没有通信,那么重启对应的浏览器。目前设置的时间是 150秒

问题 就是 tororo 如何加载 browsers-launcher 的这个 js. 目前是硬编码为

<script src="http://127.0.0.1:9997/status.js"></script>

因为 browsers-launcher 服务的端口是可配置的,所以可能会潜在存在些问题。或者是不是有更好的注入方式?

lifesinger commented 11 years ago

我的想法是,totoro 的配置文件 totoro-config.json 中,有一项配置是:

{

  insertedScript: [ 'http://127.0.0.1:9997/status.js' ]

}

通过 insertedScript,允许用户在生成的 runner.html 中插入指定的 scripts

沉鱼看看是否可行?

leoner commented 11 years ago

我觉的放到 runner.html 里面不太好,因为这个 runner.html 对应的是一个 order. 而且这个是已 iframe 的形式插入到 capture 的页面中的。 而且一个打开的浏览器中可能同时并行执行多个 runner.html . 这个时候检查起来就有点乱了.

我觉的还是应该放到 capture 的那个服务中,也就是 http://10.15.52.87:9999 这个页面中。因为这个页面才是 browsers-launcher 进行管理的。

现在这个页面的渲染是

res.send(fs.readFileSync(path.join(staticPath, 'labor.html')).toString())

那我们能否在这个地方添加一些判断,就是如果用户打开的这个url是 http://10.15.52.87:9999/?id=85534098 是这种形式的,我们就在这个渲染的页面中添加这个 js.

这个缺点还是tototoro-test 对 browsers-launcher 有了特殊的处理啊。不过如果 browsers-launcher 也启动一个代理服务的话,就好办了,不过这又回到了我们以前遇到的问题了,增加了很多复杂度。

@fool2fish

lifesinger commented 11 years ago

嗯,我错了。

那就是 totoro-server 中,有相关配置,比如:

{

  capture: { insertedScript: [ 'http://127.0.0.1:9997/status.js' ] }

}

生成的 html ( labor.html ?) 中,会根据配置插入指定的 script

leoner commented 11 years ago

现在 capture 的页面生成是这样的

app.get('/', function(req, res) {
     res.send(fs.readFileSync(path.join(staticPath, 'labor.html')).toString())
})

我觉得理论上是可以的。在渲染的这个地方检查下是否有 capture 这个配置,有的话就把这个 js 注入到页面中,不过按照现在的处理逻辑,因为 status.js 是要用到 labor.html 中已经加载的一些资源的,所以这个 js 的位默认插入的位置如果不可配置的话,那就只有插入到 </body> 前面,这样最安全.

问题

  1. 现在就是如果是用户手动打开的这个 url . 那我们也会在这个页面中添加这个 js. 这样就会多产生一个 404. 不过应该影响不大。
  2. 现在倒是有一个检查条件,就是可以检查请求的 url 是否还有 id 这个参数,如果有的话,基本上可以认为是通过 browsers-launcher 打开的。不过如果增加检查基本上又有耦合了。
  3. 我想最简单的就是在 labor.html 中稍微硬编码,就是把 status.js 中的代码直接移到 labor.html 中 . 在这个地方会对 id 进行检查,这样就不会产生多余的请求了和不必要的文件加载了。这种方式实现起来最为简单呀!
(function() {
    var href = location.href
    var reg = /id=(\d+)$/
    var id
    if (reg.test(href)) {
        id = href.match(reg)[1]
        var socket = io.connect('http://127.0.0.1:9997/status')
        socket.on('connect', function() {
            setInterval(function() {
                socket.emit('running', id)
            }, 10000)
        })
    }
}())

不过从耦合的角度来说 1 的耦合性是最小的。 大家看看能接受那种,我们就定下来了呀。

leoner commented 11 years ago

还有一种插件的方式,就是 totoro 可以配置插件,比如我们可以支持 filter 形式的插件

app.use(function(req, res, next) {
    if (req.path === '/' && req.query.id ) {
        var laborHtml = fs.readFileSync(path.join(staticPath, 'labor.html')).toString()
        laborHtml = insertedScript(laborHtml, 'http://127.0.0.1:9997/status')
        res.send(laborHtml); // 处理 加载 browsers-launcher 相关代码
    } else {
        next()
    }
})

就是我们把这段判断逻辑以插件的形式来提供,这样这个逻辑其实就是是在外部维护的。 具体插件的加载我们可以通过配置? 还是模块的形式?

{
  capture: { filter: function(req, res, next) {
      .........
  }}
}

////////
if (cfg.capture && cfg.capture.filter) {
    app.use(cfg.capture.filter)
}
lifesinger commented 11 years ago

要不先硬编码吧,先实现起来再说。保持简单、能工作最重要。未来的事情,留给未来去设计。

fool2fish commented 11 years ago

康辉的脚本自己连接socket的时候去处理,如果连接出错,就默默停掉。这样呢?

leoner commented 11 years ago

已经在 labor.html 硬编码。 默认 30秒 到 browsers 汇报一次。 browsers 也完成相应代码监控。

leoner commented 11 years ago

这个监控还可以监控到下面几种类似情况。

  1. 浏览器误关闭
  2. 浏览器崩溃关掉