框架里面集成websocket,用统一路由, 这样的框架有人用过吗?
发布于 10 年前 作者 yakczh 5673 次浏览 最后一次编辑是 8 年前
7 回复

Sails.js就是这样做的。

新建了一个sails应用 api有这几个目录 adapters controllers models policies services adapters policies services 这是干吗的 聊天的代码应该写在哪儿呢?

@yakczh 用的版本是0.9还是0.10

我用过Sails 0.9做开发,下面的信息供你参考。

1. adapter

/api/adapters目录下部署自定义的数据库适配器。常用的数据库,如MongoDB或者MySQL等,已经有对应的适配器实现,所以一般这里不需要有自己的代码文件。

2. policy

Policy是Sails的授权机制,定义了外部用户对controller的访问权限。例如,如果你正在开发Dropbox,在允许用户上载文件之前,你首先要确定用户是否已经得到认证(isAuthenticated),然后要确保他对文件夹有写的权限(canWrite),最后你还要保证目标文件夹有足够的空余空间(hasEnoughSpace)。

定义policy

所有policy都定义在api/policies文件夹下面,每个policy文件只包含一个函数。

本质上,policy也是一个Connect/Express中间件,不过它们在controller之前运行。可以定义多个policy,它们以链式方式工作——理想情况下,每个中间件就应该只完成一项功能。

例如,编写一个canWrite策略:

// policies/canWrite.js
module.exports = function canWrite (req, res, next) {
  var targetFolderId = req.param('id');
  var userId = req.session.user.id;

  Permission
  .findOneByFolderId( targetFolderId )
  .exec( function foundPermission (err, permission) {

    // 有未预料的错误发生—— 跳到默认的错误处理器 (状态码:500)
    if (err) return next(err);

    // 用户无权操作这个文件夹。
    // 这可能是因为文件夹被删除了,或者用户本来就没有权限,等等。
    if ( ! permission ) return res.redirect('/notAllowed');

    // 检查是否有写的权限
    if ( permission.type !== 'write' ) return res.redirect('/notAllowed');

    // 如果用户对目标文件夹拥有写的权限,那就继续执行后续的代码。
    next();
  });
};

使用policy

Sails的默认访问控制列表(Access Controller List, ACL)定义在config/policies.js,它的作用建立ACL和controller之间的映射。

config/policies.js的风格是声明式的。任何在api/policies下的文件,都可以在config/policies.js中直接引用。例如,api/policies/authenticated.jsconfig/policies.js中直接引用为authenticated

Sails的内置策略:

  • true - 公开访问。任何人都有权访问。
  • false - 禁止访问。任何人都不可以访问。

默认的访问控制列表是*: true,即任何人都有权访问任意的controller和action。正式发布时(production模式),应该设置为*: false,以免暴露应用逻辑。

添加策略示例

RabbitController: {

    // RabbitController的所有action的默认策略是`false`,
    // 即任何人都不无权访问。
    '*': false,

    // 对于`nurture`,应用'isRabbitMother'策略
    // (这会覆盖上面的`false`策略)
    nurture    : 'isRabbitMother',

    // 只有满足`isNiceToAnimals` 和 `hasRabbitFood` 策略的用户,
    // 才可以喂兔子
    feed : ['isNiceToAnimals', 'hasRabbitFood']
}

其中的isNiceToAnimals策略,

// api/policies/isNiceToAnimals.js
module.exports = function isNiceToAnimals (req, res, next) {

    // `req.session` 包含了当前请求用户的历史数据。

    if ( req.session.user.hasHistoryOfAnimalCruelty ) {
        return res.redirect('http://PETA.org');
    }

    if ( req.session.user.frownsAtPuppies ) {
        return res.redirect('http://www.dailypuppy.com/');
    }

    // 如果用户的记录良好,
    // 继续下一策略验证,直到controller
    next();
};

3. Service

什么是service?

不确定:从0.10版开始?

本质上,service就是库,即在应用其它地方被多次调用的代码。例如,把电子邮件服务包装成一个EmailService,方便在其它代码中调用。

如何创建一个service?

仍然以EmailService为例,

// api/services/EmailService.js
exports.sendInviteEmail = function(options) {

  var opts = {"type":"messages","call":"send","message":
    {
      "subject": "YourIn!",
      "from_email": "info@balderdash.co",
      "from_name": "AmazingStartupApp",
      "to":[
        {"email": options.email, "name": options.name}
      ],
      "text": "Dear "+options.name+",\nYou're in the Beta! Click <insert link> to verify your account"
    }
  };

  myEmailSendingLibrary.send(opts);
};

Sails会自动把service暴露给其它代码,

// 在controller中调用
EmailService.sendInviteEmail({email: 'test@test.com', name: 'test'});

@yakczh 关于adapterpoliciesservices,见下面的回复。

至于如何使用集成websocket的统一路由,注意/assets/js目录下默认生成三个文件:

  • socket.io.js
  • sails.io.js
  • app.js

在视图文件或者HTML文档中包含头两个文件,然后像app.js中的代码那样调用socket.get()等方法。服务器端跟处理普通HTTP请求一样,可以用res.json()等方法返回数据。

回到顶部