这是一篇关于ThinkJS框架的文章,由于网上对于该框架的介绍很是少,因此在这里通俗讲解一下本身对该框架基本的认识而且提供了一个练习基本功能的项目。 php
由于这是基于Node.js的框架,因此先带新手入门一点Node.js的知识。css
Node.js:简单的说Node.js就是运行在服务端的JavaScript。html
Node.js安装配置 (介绍在window和Linux上的安装Node.js的方法)node
Node.js官方文档mysql
官方文档介绍:nginx
认识包管理器npm(npm已经在安装Node.js的时候安装好了)git
当咱们在Node.js上开发时,会用到不少别人写的JavaScript代码。若是咱们须要使用别人写的某个包,每次都根据名称搜索一下官方文档,下载代码,解压,再使用,很是繁琐。因而一个集中管理的工具应运而生:你们都把本身开发的模块打包后放到npm官网上,若是要使用,直接经过npm安装就能够直接使用,无论代码存在哪,应该从哪下载。github
更重要的是,若是咱们要使用模块A,而模块A又依赖于模块B,模块B又依赖于其余的模块,那么npm能够根据依赖关系,把全部依赖的包都下载下来并管理起来。不然,靠咱们本身手动管理,确定是麻烦又容易出错。web
了解Node.js应用的几个组成部分:redis
建立Node.js应用:
步骤一:引入required模块
使用require指令载入http模块,并将实例化的HTTP赋值给变量http,实例以下:
var http = require('http');
复制代码
步骤二:建立服务器
接下来咱们使用 http.createServer()
方法建立服务器,并使用listen方法绑定8888端口。函数经过request
,response
参数来接收和响应数据。实例以下:
var http = require('http'); //请求Node.js自带的http模块,而且把它赋值给http变量
http.createServer(function (request, response) { //调用http模块提供的模块
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
response.end('Hello World\n');
}).listen(8888);
// 终端打印以下信息
console.log('Server running at http://127.0.0.1:8888/');
复制代码
Express和Koa(典型框架)
Express:轻量灵活的的node.js 框架,能够快速的搭建应用,使用普遍。Express官方文档
Koa:由Express原班人马打造,致力于成为web应用和API开发领域中的一个更小、更富有表现力、更健壮的基石。经过利用async函数,koa帮你丢弃回调函数,并有力的加强错误处理。Koa官方文档
Express和Koa是node.js最基础的两个后端框架。由于构建一个app仍须要些不少脚手架代码,因而在他们基础上出现了不少其余框架来减小编写这类代码。(例如:ThinkJS,egg.js等)
介绍:ThinkJS是一款面向将来开发的Node.js框架,整合了大量的项目最佳实践,让企业级开发变得简单、高效。从3.0开始,框架底层基于Koa2.x实现,兼容Koa的全部功能。
特性:
middleware
Extend
、Adapter
等插件方式async/await
处理异步问题、再也不支持*/yield
方式借助ThinkJS提供的脚手架,能够快速的建立一个项目。为了可使用更多的ES6特性,框架要求node.js的版本至少是6.x,建议使用LTS版本。
npm install -g think-cli
复制代码
安装完成后,系统中会有thinkjs命令(能够经过thinkjs-v查看think-cli版本号)
thinkjs new demo //建立名为demo的项目
npm install //安装依赖
npm start //运行项目
复制代码
项目结构
默认建立的项目结构以下:
|--- development.js //开发环境下的入口文件
|--- nginx.conf //nginx 配置文件
|--- package.json
|--- pm2.json //pm2 配置文件
|--- production.js //生产环境下的入口文件
|--- README.md
|--- src
| |--- bootstrap //启动自动执行目录
| | |--- master.js //Master 进程下自动执行
| | |--- worker.js //Worker 进程下自动执行
| |--- config //配置文件目录
| | |--- adapter.js // adapter 配置文件
| | |--- config.js // 默认配置文件
| | |--- config.production.js //生产环境下的默认配置文件,和 config.js 合并
| | |--- extend.js //extend 配置文件
| | |--- middleware.js //middleware 配置文件
| | |--- router.js //自定义路由配置文件
| |--- controller //控制器目录
| | |--- base.js
| | |--- index.js
| |--- logic //logic 目录
| | |--- index.js
| |--- model //模型目录
| | |--- index.js
|--- view //模板目录
| |--- index_index.html
复制代码
Config(配置)
实际项目中,确定须要各类配置,包括:框架须要的配置以及项目自定义的配置。ThinkJS将全部的配置都统一管理,文件都放在src/config/目录下,并根据不一样的功能划分为不一样的配置文件。
config.js
通用的一些配置adapter.js
adapter配置 (数据库的配置)router.js
自定义路由配置middleware.js
middleware配置validator.js
数据校验配置extend.js
extend 配置配置格式
// src/config.js
module.exports = {
port: 1234,
redis: {
host: '192.168.1.2',
port: 2456,
password: ''
}
}
复制代码
配置值便可以是一个简单的字符串,也能够是一个复杂的对象,具体是什么类型根据具体的需求来决定。
使用配置
框架提供了在不一样环境下不一样的方式快速获取配置:
ctx.config(key)
来获取配置controller.config(key)
来获取配置think.config(key)
来获取配置实际上,ctx.config
和controller.config
是基于think.config
包装的一种更方便的获取配置的方式。
Adapter(适配器)
Adapter是用来解决一类功能的多种实现,这些实现提供一套相同的接口,相似设计模式里的工厂模式。如:支持多种数据库,支持多种模板引擎等。经过这种方式,能够很方便地在不一样的类型中进行切换。Adapter通常配合Extend一块儿使用。
框架默认提供了不少Adapter,如:View、Model、Cache、Session、Websocket
,项目中也能够根据须要进行扩展,也能够引入第三方的Adapter。
Adapter配置
Adapter的配置文件为src/config/adapter.js
,格式以下:
const nunjucks = require('think-view-nunjucks');
const ejs = require('think-view-ejs');
const path = require('path');
exports.view = {
type: 'nunjucks', // 默认的模板引擎为 nunjucks
common: { //通用配置
viewPath: path.join(think.ROOT_PATH, 'view'),
sep: '_',
extname: '.html'
},
nunjucks: { // nunjucks 的具体配置
handle: nunjucks
},
ejs: { // ejs 的具体配置
handle: ejs,
viewPath: path.join(think.ROOT_PATH, 'view/ejs/'),
}
}
exports.cache = {
...
}
复制代码
Adapter 配置支持运行环境,能够根据不一样的运行环境设置不一样的配置,如:在开发环境和生产环境的数据库通常都是不同的,这时候能够经过 adapter.development.js
和 adapter.production.js
存放有差别的配置,系统启动后会读取对应的运行环境配置和默认配置进行合并。
Adapter配置解析
Adapter 配置存储了全部类型下的详细配置,具体使用时须要对其解析,选择对应的一种进行使用。好比上面的配置文件中,配置了nunjucks
和 ejs
二种模板引擎的详细配置,但具体使用时一种场景下确定只会用其一种模板引擎。固然,配置解析并不须要使用者在项目中具体调用,通常都是在插件对应的方法里已经处理。
Adapter使用
Adapter 都是一类功能的不一样实现,通常是不能独立使用的,而是配合对应的扩展一块儿使用。如:view Adapter(think-view-nunjucks、think-view-ejs)
配合 think-view
扩展进行使用。
数据库:(model Adapter
配合think-mongo
扩展进行使用)
model adapter
/**
* model adapter config
* @type {Object}
*/
exports.model = {
type: 'mongo', // 默认使用的类型,调用时能够指定参数切换
common: { // 通用配置
logConnect: true, // 是否打印数据库链接信息
logger: msg => think.logger.info(msg) // 打印信息的 logger
},
mongo: {
host: '127.0.0.1',
port: 27017,
user: '',
password: '',
database: 'manannan', // 数据库名称
options: ''
}
};
复制代码
extend
const view = require('think-view');
const model = require('think-model');
const cache = require('think-cache');
const session = require('think-session');
const mongo = require('think-mongo');
module.exports = [
view, // make application support view
model(think.app), ////将 think.app 传递给 model 扩展
mongo(think.app),
cache,
session
];
复制代码
Extend(扩展)
虽然框架内置了不少功能,但在实际项目开发中,提供的功能仍是远远不够的。3.0 里引入了扩展机制,方便对框架进行扩展。支持的扩展类型为:think
、application
、context
、request
、response
、controller
、logic
和 service
。
框架内置的不少功能也是扩展来实现的,如:Session
、Cache
。
Context(上下文)
Context是Koa中处理用户请求中的一个对象,贯穿整个请求生命周期。通常在middleware
、controller
、logic
中使用,简称ctx。
框架里继承了该对象,并经过 Extend 机制扩展了不少很是有用的属性和方法。
例如:
ctx.state
在中间件之间传递信息以及将信息发送给模板时,推荐的命名空间。避免直接在 ctx 上加属性,这样可能会覆盖掉已有的属性,致使出现奇怪的问题。
ctx.state.user = await User.find(id);
复制代码
这样后续在 controller 里能够经过 this.ctx.state.user
来获取对应的值。
module.exports = class extends think.Controller {
indexAction() {
const user = this.ctx.state.user;
}
}
复制代码
ctx.header
获取全部的 header 信息,等同于 ctx.request.header
。
const headers = ctx.headers;
复制代码
ctx.headers
获取全部的 header 信息,等同于ctx.header
。
ctx.url
获取请求地址。
Middleware称之为中间件,是Koa中一个很是重要的概念,利用中间件,能够很方便的处理用户的请求。
中间件格式为一个高阶函数,外部的函数接收一个 options
参数,这样方便中间件提供一些配置信息,用来开启/关闭一些功能。执行后返回另外一个函数,这个函数接收 ctx
, next
参数,其中 ctx
为 context
的简写,是当前请求生命周期的一个对象,存储了当前请求的一些相关信息,next
为调用后续的中间件,返回值是 Promise,这样能够很方便的处理后置逻辑。(执行过程是个洋葱模型)
配置格式
为了方便管理和使用中间件,框架使用的配置文件来管理中间件,配置文件为src/config/middleware.js
。
const path = require('path')
const isDev = think.env === 'development'
module.exports = [
{
handle: 'meta', // 中间件处理函数
options: { // 当前中间件须要的配置
logRequest: isDev,
sendResponseTime: isDev,
},
},
{
handle: 'resource',
enable: isDev, // 是否开启当前中间件
options: {
root: path.join(think.ROOT_PATH, 'www'),
publicPath: /^\/(static|favicon\.ico)/,
},
}
]
复制代码
配置项为项目中要使用的中间件列表,每一项支持handle
,enable
,options
,match
等属性。
handle
中间件的处理函数,可使用系统内置的,也能够是外部导入的,也能够是项目里的中间件。
enable
是否开启当前的中间件。
options
传递给中间件的配置项,格式为一个对象,中间件里获取到这个配置。
match
匹配特定的规则后才执行该中间件,支持两种方式,一种是路径匹配,一种是自定义函数匹配。
框架内置的中间件
框架内置了几个中间件,能够经过字符串的方式直接引用。
meta
显示一些meta信息。如:发送ThinkJS版本号,接口的处理时间等resource
处理静态资源,生产环境建议关闭,直接用webserver处理便可trace
处理报错,开发环境将详细的报错信息显示处理,也能够自定义显示错误页面payload
处理表单提交和文件上传,相似于koa-bodyparser
等middleware
router
路由解析,包含自定义路由解析logic
logic调用,数据校验controller
controller和action项目中自定义的中间件
有时候项目中根据一些特定须要添加中间件,那么能够放在src/middleware
目录下,而后就能够直接经过字符串的方式引用。
// middleware/log.js
const defaultOptions = {
consoleExecTime: true // 是否打印执行时间的配置
}
module.exports = (options = {}) => {
// 合并传递进来的配置
options = Object.assign({}, defaultOptions, options);
return (ctx, next) => {
if(!options.consoleExecTime) {
return next(); // 若是不须要打印执行时间,直接调用后续执行逻辑
}
const startTime = Date.now();
let err = null;
// 调用 next 统计后续执行逻辑的全部时间
return next().catch(e => {
err = e; // 这里先将错误保存在一个错误对象上,方便统计出错状况下的执行时间
}).then(() => {
const endTime = Date.now();
console.log(`request exec time: ${endTime - startTime}ms`);
if(err) return Promise.reject(err); // 若是后续执行逻辑有错误,则将错误返回
})
}
}
复制代码
用法:在/src/config/middleware.js
module.exports = [
{
handle: 'log', // 中间件处理函数
options: { // 当前中间件须要的配置
consoleExecTime: true,
},
}
]
复制代码
引入外部的中间件
引入外部的中间件很是简单,只须要require
进来便可。
const cors = require('koa2-cors');
module.exports = [
...,
{
handle: cors,
option: {
origin: '*'
}
},
...
]
复制代码
MVC模型中,控制器是用户请求的逻辑处理部分。好比:将用户相关的操做都放在user.js
里,每个操做就是里面的一个Action。
建立controller
项目里的controller须要继承think.Controller
类,这样能使用一些内置的方法。固然项目中能够建立一些通用的基类,而后实际的controller都继承自这个基类。
项目建立时会自动建立一个名为base.js
的基类,其余的controller
继承该类便可。
Action执行
Action执行是经过中间件think-controller
来完成的,经过ctx.action
值在controller寻找xxxAction的方法名并调用,且调用相关的魔术方法,具体顺序为:
实例化 Controller 类,传入 ctx
对象
若是方法 __before 存在则调用,若是返回值为false
,则中止继续执行
若是方法xxxAction
存在则执行,若是返回值为 false
,则中止继续执行
若是方法 xxxAction
不存在但 __call 方法存在,则调用 __call,若是返回值为 false
,则中止继续执行
若是方法 __after 存在则执行前置操做__before
若是方法 __after 存在则执行
前置操做 __before
项目中,有时候须要在一个统一的地方作一些操做,如:判断是否已经登陆,若是没有登陆就不能继续后面行为。此种状况下,能够经过内置的 __before
来实现。
__before
是在调用具体的 Action 以前调用的,这样就能够在其中作一些处理。
若是类继承须要调用父级的 __before
方法的话,能够经过 super.__before
来完成。
后置操做 __after
后置操做 __after
与__before
对应,只是在具体的 Action 执行以后执行,若是具体的 Action 执行返回了 false
,那么 __after
再也不执行。
当在Action里处理用户的请求时,常常要先获取用户提交过来的数据,而后对其校验,若是校验没问题后才能进行后续的操做;当参数校验完成后,有时候还须要进行权限判断等,这些都判断无误后才能进行真正的逻辑处理。若是将这些代码都放在一个Action里,势必让Action的代码很是复杂且冗长。
为了解决这个问题,ThinkJS在控制器前面增长了一层Logic,Logic里的Action和控制器里的Action一一对应,系统在调用控制器里的Action以前会自动调用Logic里的Action。
当用户访问一个地址时,须要有一个对应的逻辑进行处理。传统的处理方式下,一个请求对应的文件,如访问是/user/about.php
,那么就会在项目对应的目录下有/user/about.php
这个实体文件。这种方式虽然能解决问题,但会致使文件不少,同时可能不少文件逻辑功能其实比较简单。
在如今的MVC开发模型里,通常都是经过路由来解决此类问题。解决方式为:先将用户的全部请求映射到一个入口文件(如:index.php
),而后框架解析当前请求的地址,根据配置或者约定解析出对应要执行的功能,最后去调用而后响应用户的请求。
因为Node.js是本身启动HTTP(S)服务的,因此已经将用户的请求汇总到一个入口文件了,这样处理路由映射就更简单了。
在ThinkJS中,当用户访问一个URL时,最后是经过controller里具体的action来响应的。因此就须要解析出URL对应的controller和action,这个解析工做是经过think-router
模块来实现的。
路由配置
think-router
是一个middleware,项目建立时已经默认加到配置文件src/config/middleware.js
里了。
路径预处理
当用户访问服务时,经过ctx.url
属性,能够获得初始的pathname
,可是为了方便后续经过 pathname
解析出controller和action,须要对pathname进行预处理。好比去除URL中.html
后缀等操做,最后获得真正后续所需解析的pathname
。默认的路由解析规则为/controller/action
.
对于ThinkJS中的controller,能够不用写router,也能够自定义router。
pathname | 子集控制器 | controller | action | 备注 |
---|---|---|---|---|
/ | 无 | index | index | controllller、action为配置的默认值 |
/user | 无 | user | index | action为配置的默认值 |
/user/login | 无 | user | login | |
/console/user/login | 有 | console/user | login | 有子集控制器console/user |
/console/user/login/aaa/b | 有 | console/user | login | 剩余的aaa/b不在解析 |
自定义路由规则
虽然默认的路由解析方式可以知足需求,但有时候会致使URL看起来不够优雅,咱们更但愿URL比较简短,这样会更利于记忆和传播。框架提供了自定义路由来处理这种需求。
自定义路由规则配置文件为src/config/router.js
,路由规则为二维数组。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,不少接口都是异步的,如:文件操做、网络请求。虽然提供了文件操做的同步接口,但这些接口是阻塞式的,非特殊状况下不要使用它。
对于异步接口,官方的 API 都是 callback
形式的,可是这种方式在业务逻辑复杂后,很容易出现callback hell
的问题,为了解决这个问题相继出现了event
、Promise
、Generator
function
、Async function
等解决方案,ThinkJS使用async function
方案来解决异步问题。
Async functions
Async functions 使用async/await
语法定义函数,如:
async function fn() {
const value = await getFromApi();
doSomethimgWithValue();
}
复制代码
await
时必需要有 async
,但有 async
不必定非要有 await
Async functions
能够是普通函数的方式,也能够是 Arrow functions
的方式await
后面须要接 Promise
,若是不是 Promise
,则不会等待处理Promise
返回值和 await
后面接的表达式均为 Promise
,也就是说 Async functions
以 Promise
为基础。若是 await
后面的表达式返回值不是 Promise
,那么须要经过一些方式将其包装为 Promise
。
在项目开发中,常常须要操做数据库(如:增删改查等功能),手工拼写 SQL 语句很是麻烦,同时还要注意 SQL 注入等安全问题。为此框架提供了模型功能,方便操做数据库。
扩展模型功能
框架默认没有提供模型的功能,须要加载对应的扩展才能支持,对应的模块为 think-model
。修改扩展的配置文件 src/config/extend.js
,添加以下的配置:
const model = require('think-model');
module.exports = [
model(think.app) // 让框架支持模型的功能
];
复制代码
配置数据库
模型因为要支持多种数据库,因此配置文件的格式为 Adapter 的方式,文件路径为 src/config/adapter.js
Mysql
Mysql 的 Adapter 为 think-model-mysql
,底层基于 mysql 库实现,使用链接池的方式链接数据库,默认链接数为 1。
const mysql = require('think-model-mysql');
exports.model = {
type: 'mysql',
mysql: {
handle: mysql, // Adapter handle
user: 'root', // 用户名
password: '', // 密码
database: '', // 数据库
host: '127.0.0.1', // host
port: 3306, // 端口
connectionLimit: 1, // 链接池的链接个数,默认为 1
prefix: '', // 数据表前缀,若是一个数据库里有多个项目,那项目之间的数据表能够经过前缀来区分
}
复制代码
建立模型文件
模型文件放在 src/model/
目录下,继承模型基类 think.Model
,文件格式为:
// src/model/user.js
module.exports = class extends think.Model {
getList() {
return this.field('name').select();
}
}
复制代码
实例化模型
项目启动时,会扫描项目下的全部模型文件,扫描后会将全部的模型类存放在think.app.models
对象上,实例化时会从这个对象上查找,若是找不到则实例化模型基类 think.Model。
CRUD 操做
think.Model
基类提供了丰富的方法进行 CRUD 操做,下面来一一介绍。
有时候关系数据库并不能知足项目的需求,须要 MongoDB 来存储数据。框架提供了think-mongo
扩展来支持 MongoDB,该模块是基于mongodb
实现的。
配置MongoDB数据库
MongoDB 的数据库配置复用了关系数据库模型的配置,为 adapter 配置,放在 model 下。文件路径为 `src/config/adapter.js`
exports.model = {
type: 'mongo', // 默认使用的类型,调用时能够指定参数切换
common: { // 通用配置
logConnect: true, // 是否打印数据库链接信息
logger: msg => think.logger.info(msg) // 打印信息的 logger
},
mongo: {
host: '127.0.0.1',
port: 27017,
user: '',
password: '',
database: '', // 数据库名称
options: {
replicaSet: 'mgset-3074013',
authSource: 'admin'
}
}
}
复制代码
扩展MongoDB功能
修改扩展的配置文件src/config/extend.js
,添加以下的配置:
const mongo = require('think-mongo');
module.exports = [
mongo(think.app) // 让框架支持模型的功能
]
复制代码
添加完扩展后,会注入 think.Mongo
、think.mongo
、ctx.mongo
和 controller.mongo
方法,其中 think.Mongo
为 Mongo 模型的基类文件,其余为实例化 Mongo 模型的方法,ctx.mongo
和 controller.mongo
是 think.mongo
方法的包装。
建立模型文件
模型文件放在 src/model/
目录下,继承模型基类 think.Mongo
,文件格式为:
// src/model/user.js
module.exports = class extends think.Mongo {
getList() {
return this.field('name').select();
}
}
复制代码
实例化模型
项目启动时,会扫描项目下的全部模型文件(目录为 src/model/
),扫描后会将全部的模型类存放在 think.app.models
对象上,实例化时会从这个对象上查找,若是找不到则实例化模型基类 think.Mongo
。
API
框架中内置 think
全局对象,方便在项目中随时随地使用。
API
启动自定义
当经过 npm start
或者node production.js
来启动项目时,虽然能够在这些入口文件里添加其余的逻辑代码,但并不推荐这么作。系统给出了其余启动自定义的入口。
bootstrap
系统启动时会加载 src/boostrap/
目录下的文件,具体为:
src/bootstrap/master.js
src/bootstrap/worker.js
因此能够将一些须要在系统启动时就须要执行的逻辑放在对应的文件里执行。
Service 文件存放在 src/service/
目录下,文件内容格式以下:
// src/service/user.js
module.exports = class extends think.Service {
find(id){
return {username:'123',id:id}
}
}
复制代码
Service
都继承 think.Service
基类,但该基类不提供任何方法,能够经过 Extend
进行扩展。
实例化Service类
能够经过 think.service
方法实例化Service
类,在控制器、ctx 也有对应的 service 方法,如:ctx.service
、controller.service
,这些方法都是 think.service
的快捷方式。
//controller
think.service('user').find(111)
复制代码
项目启动时,会扫描项目下全部的 services
文件,并存放到 think.app.services
对象下,实例化时会从该对象上查找对应的类文件,若是找不到则报错。
以上就是对该框架的基本认识,若是是新入手该框架,那么了解了src下的基本配置,包括如何添加数据库的适配器(adapter)同时扩展模型(extend),以后在model层进行数据库的操做,controller层进行先后台交互即可以实现接口(api)功能,以后的进阶就须要更加深刻的学习了。
注意:该项目使用的是mongoDB数据库。 项目基本功能介绍:
1.获取前台请求头(token),实现用户身份验证
// controller/base.js
const jwt = require('jsonwebtoken');
const Token = require('../logic/token');
module.exports = class extends think.Controller {
async __before() {
if (this.ctx.config('allowUrls').indexOf(this.ctx.url) === -1) {
if (!this.ctx.request.header.authorization) {
this.fail(401, '没有认证');
return false;
} else {
let payload = null;
const authorization = this.ctx.request.header.authorization;
const secret = this.ctx.config('secret');
try {
payload = jwt.verify(authorization, secret);
// 该验证函数在logic/token
await Token.verify(authorization);
this.ctx.state.user_id = payload._id;
} catch (error) {
this.fail(error.code, error.message);
return false;
}
}
}
}
};
复制代码
2.设置token,存入redis,设置过时时间
//controller/user.js
// 用户登陆
async loginUserAction() {
const user = await this.mongo('user').loginUser(this.post('account'), this.post('password'));
if (think.isEmpty(user)) {
this.fail(403, '登录失败,用户名或密码错误');
} else {
let payload = {_id: user._id, account: user.account, password: user.password};
let token = jwt.sign(payload, think.config('secret'), {expiresIn: 60 * 60 * 24 * 30});
redis.set(token, payload._id.toString());
redis.expire(token, token_expire);
return this.success({token}, '用户登录成功');
}
}
复制代码
3.实现wamp实时推送消息
//controller/wamp.js
const autobahn = require('autobahn');
const wampConfig = require('../config/config').wamp;
const options = wampConfig.options;
module.exports = {
roomInfo: (args) => {
const connection = new autobahn.Connection(options);
console.log("链接信息",connection);
connection.onopen = function (session) {
session.publish(wampConfig.definedTopic, [args]);
console.log("wamp发布的主题是:" + wampConfig.definedTopic);
console.log(args);
};
console.log("end======");
connection.open();
}
};
复制代码
//使用
/**
* @param {any} user
* @returns
* 添加房屋信息后推送wamp确认消息
*/
async addRoomWamp(roomInfo) {
let sum = 0;
const rooms = await this.model('room').add(roomInfo);
if(!(think.isEmpty(rooms))){
const data = {sum: "lalal"};
wamp.roomInfo(data);
}
}
复制代码
4.身份权限验证
//获取全部房源信息
async getAllRoomsAction() {
const userInfo = await this.mongo('user').findUserDetailInfo(this.ctx.state.user_id);
console.log("userInfo", userInfo);
if (!(think.isEmpty(userInfo)) && userInfo.role === 'admin') {
this.success(await this.mongo('room').getAllRooms());
} else {
this.fail("没有权限访问");
}
}
复制代码
(实现方式是进项用户角色判断,可使用acl,以后项目会进行更新)