主要介绍node.js的框架的技术选型和框架搭建,以及如何在服务器上部署发布。这里客户端使用小程序来介绍。小程序主要功能涉及到用户受权登陆,地图定位,webSocket发送定位,二维码扫描添加设备。javascript
Koa+Typescript,除了自己类型系统对数据库的数据模型定义有好处外。Koa中间件的context有不少库或者用户自定义数据结构挂载在上面,若是没有类型声明,开发者可能不知道context上有哪些类型,致使工程维护性增长。html
Mongodb(www.mongodb.com/cn)Mongodb自己查询语法是JS写的,很符合前端的使用。基于文档处理,自己查询速度也比较快。关联表的结构设计,也至关简单,学习成本低。对于前端来讲对表的设计经验不足,若是使用mysql之类的关系型数据库,若是设计不当,极可能致使性能问题。前端
pm2是node社区比较成熟的进程管理框架,自己自带日志查看,错误重启,服务器部署的能力。java
总体工程的设计使用mvc的结构,Koa中间件,使用TS类型辅助。node
-src --api 接口的api好比微信小程序登陆受权相关的api --config 配置项 --const 常量 --controllers 控制层 --interfaces 接口 --middleware 自定义中间层 --modules 模型层,主要放数据库相关的模型数据 --types ts 拓展类型 --utils 工具包,放请求,logger,配置,jwt相关的工具 --server.ts 服务启动入口 -.env 全局常量配置(用户自定义的,不提交git) -.env.example 全局常量配置 -ecosystem.config.js pm2的配置文件,部署的时候自动执行mysql
数据库:docs.mongodb.com/manual/inst… 可视化工具:www.mongodb.com/download-ce… 选择社区免费版本linux
输入mongo就能够链接。最好配置用户和密码,虽然本地未必要配置密码,可是服务端确定要配置的,因此就先介绍下如何配置。nginx
db.createUser({ user: "useradmin", pwd: "adminpassword", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] }) 复制代码
security:
authorization: enabled
复制代码
6.重启服务git
brew services restart
复制代码
7.建立一个应用的数据库 use app_db 8.对这个应用的数据库建立权限web
// 拥有者 db.createUser({ user: "youruser", pwd: "yourpassword", roles: [{ role: "dbOwner", db:"app_db" }] }) // 可读写 db.createUser({ user: "youruser2", pwd: "yourpassword2", roles: [{ role: "readWrite",db: "app_db" }] }) 复制代码
9.最后能够输入链接来启动
mongodb://youruser2:yourpassword2@localhost/app_db 复制代码
十、可使用可视化工具compass链接
重命名.env.example为.env,基本的.env代码以下
# 这个是ENV全局变量,其中变量NODE_ENV在开始执行建立, development: 是开发环境,production:是生产环境。 # mongodb的地址 production生产环境依赖 MONGODB_URI=mongodb://<mlab_user>:<mlab_password>@<mlab_connection_url> # mongodb的地址 developmet开发环境依赖 MONGODB_URI_LOCAL=mongodb://localhost:27017/go_app # token的秘钥 TOKEN_KEY=ting.ting@huang_GO!GO!GO!!! # 微信AppId WX_APP_ID=wx0840e0b26c481112 # 微信的AppSecret WX_APP_SECRET=34c4824eb1115281d249e85dba4f8157 复制代码
安装ts-node和typescript到开发环境
使用npm start命令启动,安装nodemon到开发环境,而后以下输入命令
nodemon --watch 'src/**/*' -e ts,tsx --exec 'ts-node' ./src/server.ts
复制代码
使用vscode,这里是我推荐的方式。而后配置launch.json,使用F5启动、调试。
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"runtimeArgs": ["-r", "ts-node/register"],
"args": ["${workspaceFolder}/src/server.ts"],
"env": {
"NODE_ENV": "development"
},
"sourceMaps": true,
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
复制代码
服务器使用CentOS,之因此不使用ubuntu,是由于不必使用到界面,也是大多数服务器采用到的方案。固然使用ubuntu也没什么问题,内核都同样。而后使用yum安装一些经常使用的工具库。
首先在本机上建立ssh公钥和秘钥,而后去服务器添加公钥,而后链接服务器。 命令以下 ssh -q -l root -p 22 111.230.28.25
和开发环境配置相似,只是都是linux下的,建立密码和本地使用compass链接验证。这里注意记得在要给服务开端口。
网上教程不少,我这里主要介绍使用yum来安装Nginx,使用yum安装很是简单。使用systemctl来启动(固然也有使用service,可是不能开机启动了),有兴趣想了解systemctl相关命令能够看看这个www.ruanyifeng.com/blog/2016/0…
$ sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
复制代码
$ sudo yum install nginx
复制代码
安装完Nginx,会生成一个配置文件,路径是:/etc/nginx/nginx.conf。输入命令 vim nginx.conf 来编辑
user nginx; worker_processes 1; events { worker_connections 1024; } error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; http { server { listen 80; server_name localhost; location / { proxy_pass http://127.0.0.1:8088; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ^~ /websocket/ { proxy_pass http://127.0.0.1:8088; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } } server { listen 443 ssl; server_name localhost ssl on; ssl_certificate cert/2760618_www.dayuan.tech.pem; ssl_certificate_key cert/2760618_www.dayuan.tech.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!3DES:!aNULL:!eNULL; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:8088; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ^~ /websocket/ { proxy_pass http://127.0.0.1:8088; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; gzip on; include /etc/nginx/conf.d/*.conf; } 复制代码
设置开机启动
systemctl enable nginx
复制代码
启动服务
systemctl start nginx
复制代码
中止服务
systemctl stop nginx
复制代码
从新启动服务
systemctl restart nginx
复制代码
热更新,也就是不想从新启动整个服务,只想从新加载配置文件
systemctl reload nginx
复制代码
和这里图有点不一样的是,登陆凭证校验完后,我是使用一个会过时token来验证。验证成功后客户端会发送一次获取头像和昵称等用户基本信息的请求,获取后,再把这些传回给开发者服务器。之后用户基本信息都从开发者服务器获取就好。 还有一个主意点微信的auth.getAccessToken,须要按期获取,具体以下developers.weixin.qq.com/miniprogram…。
// 路由模块使用前须要先安装和实例化 import Router from 'koa-router' import fs from 'fs' import checkToken from '@/middleware/checkToken' const router = new Router() /** * 将全部controller下的文件都加载到router */ let urls = fs.readdirSync(__dirname + '/../controllers') // 全部请求api路由前都要通过这个控制层 router.use('/api', checkToken) urls.forEach((element: string) => { let module = require(__dirname + '/../controllers/' + element) router.use('/api', module.default.routes(), module.default.allowedMethods()) }) export default router 复制代码
若是不用Typegoose
interface Car { model?: string; } interface Job { title?: string; position?: string; } interface User { name?: string; age: number; job?: Job; car: Car | string; } mongoose.model('User', { name: String, age: { type: Number, required: true }, job: { title: String; position: String; }, car: { type: Schema.Types.ObjectId, ref: 'Car' } }); mongoose.model('Car', { model: string, }); 复制代码
用了之后
class Job { @prop() title?: string; @prop() position?: string; } class Car extends Typegoose { @prop() model?: string; } class User extends Typegoose { @prop() name?: string; @prop({ required: true }) age!: number; @prop() job?: Job; @prop({ ref: Car }) car?: Ref<Car>; } 复制代码
不管是kos还webSocket都是调用Node标准的http模块建立的http.Server监听的,koa只是把响应的函数注册到http.Server,同理WebSocket也能够把响应的函数注册到http.Server,因此可使用同一个端口。我是对webSokcet作了一层封装,其中链接的代码以下
function connectSocket(server: Server) { wss = new WebSocketServer({ server }) wss.on('connection', onConnection) server.on('upgrade', (request, socket, head) => { const pathname = url.parse(request.url).pathname if (pathname === '/websocket/location') { wss.handleUpgrade(request, socket, head, ws => { wss.emit('connection', ws, request) }) } }) } 复制代码