node学习

254 阅读5分钟

什么是node.js

定义:基于chrome v8引擎的javascript 运行环境

特点:事件驱动,非阻塞式I/O的模型,轻量和高效,单线程、单进程

nodejs能做什么?

可以解析js代码(没有浏览器安全级别的限制)

提供很多系统级别的API:

文件的读写

进程的管理

网络的通信...

v8

谷歌开源的一个高性能 JavaScript 引擎 采用 C++ 编写 Google Chrome 浏览器用的就是这个引擎 V8 可以单独运行,也可以嵌入 C++ 应用当中 V8 会编译、执行 JavaScript 代码,并一样会管理内存、垃圾回收 V8 的高性能以及跨平台等特性,所以它也是 Node.js 的 JavaScript 引擎 JIT 编译出即时机器码,极大提高效率 借鉴java vm 垃圾回收,精确垃圾回收

安装nodemon 实时监测文件的变化

npm install -g nodemon //全局安装

模块包/CommonJS规范

www.commonjs.org javascript.ruanyifeng.com/nodejs/modu…

每个文件就是一个模块,在模块里面定义的变量、函数、类都是私有的

module 代表的当前模块 ,exports属性,代表向外提供接口

require加载模块,读取并执行一个js文件,然后返回该模块的exports对象

模块加载的顺序,按照代码中出现的顺序

模块可以多次加载,第一次加载运行之后,会被缓存

require内部处理流程

模块内容导出:

module.exports = "字符串";//可以的
module.exports.msg = '字符串'//可以的
exports.msg = '字符串'//可以的
exports = '字符串'//不行的

检查Moducle._cache, 是否缓存了指定模块

如果缓存没有的话,就创建一个新的module实例将它保存到缓存

module.load()去加载指定的模块

如果解析的过程中,出现异常,就从缓存中删除该模块

返回该模块的module.exports

node.js官网:nodejs.cn/api/

在 Node.js 模块系统中,每个文件都被视为一个独立的模块。

常用内置js模块

参考学习:github.com/chyingp/nod…

const http = require('http');
const path = require('path');
const qs = require('querystring');
const fs = require('fs')
const url = require('url');
const crypto = require('crypto');

版本号命名规则

GNU 风格的版本号命名格式

语义版本号分为X.Y.Z三位, 分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。

  • 如果只是修复bug,需要更新Z位。
  • 如果是新增了功能,但是向下兼容,需要更新Y位。
  • 如果有大变动,向下不兼容,需要更新X位。

软件阶段说明

  • Base:此版本表示该软件仅仅是一个假页面链接,通常包括所有的功能和页面布局,但是页面中的功能都没有做完整的实现,只是做为整体网站的一个基础架构。 
  • Alpha :软件的初级版本,表示该软件在此阶段以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改,是测试版本。测试人员提交Bug经开发人员修改确认之后,发布到测试网址让测试人员测试,此时可将软件版本标注为alpha版。
  • Beta :该版本相对于Alpha 版已经有了很大的进步,消除了严重错误,但还需要经过多次    测试来进一步消除,此版本主要的修改对象是软件的UI。修改的的Bug 经测试人员测试确认后可发布到外网上,此时可将软件版本标注为 beta版。 
  • RC :该版本已经相当成熟了,基本上不存在导致错误的Bug,与即将发行的正式版本相差无几。
  • Release:该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式的版本,是最终交付用户使用的一个版本。该版本有时也称标准版。

Package.json版本号规则

  • npm install
  • npm install @version
  • 波浪符号(~) ~1.15.2 >=1.15.2 <1.16.0
  • 插入符号(^) ^3.3.4 >=3.3.4 <4.0.0

socket

websocket

www.runoob.com/html/html5-…

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

index.html

<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #msglist {
      width: 400px;
      height: 500px;
      background: #eeeeee;
    }
  </style>
</head><body>
  <div id="msglist"></div>
  <textarea id="msg" rows="5" cols="10"></textarea>
  <button id="btn">留言</button><script>
​
    var $btn = document.querySelector("#btn");
    var $msg = document.querySelector("#msg")
    var $list = document.querySelector('#msglist')
​
    //http => new WebSocket('ws://***')
    //https => new WebSocket('wss://***') 不能是ip
    var ws = new WebSocket('ws://localhost:8099')
​
    function wsEvent() {
      //用于指定当从服务器接受到信息时的回调函数
      ws.onmessage = (msg) => {
        console.log(msg.data)
        $list.innerHTML += msg.data + '<br>';
      }
​
      //用于连接成功之后的回调函数
      ws.onopen = () => {
        console.log('open ...')
      }
​
      //用于指定连接关闭后的回调函数
      ws.onclose = () => {
        console.log('close')
        reconnect()
      }
​
      ws.onerror = () => {
        console.log('error')
        reconnect()
      }
​
    }
​
    wsEvent();
​
    $btn.addEventListener('click', () => {
      //数据的发送
      ws.send($msg.value)
​
    })
​
    //重连
    function reconnect() {
      if (ws.readyState === 2 || ws.readyState === 3) {
        ws = new WebSocket('ws://localhost:8099');
        wsEvent();
      }
    }
​
  </script></body></html>

websocketServer.js

const ws = require('ws');
​
var websocketServer = new ws.Server({ port: 8099 });
​
//所有的客户端列表
var clientlist = {}
var id = 0;
​
websocketServer.on('connection', (client) => {
  client.id = id++;
  clientlist[id] = client;
  console.log('connection...')
  client.send('welcome to back')
  client.on('message', (msg) => {
    console.log(msg)
    boardcast(client.id + ":" + msg);
  })
​
  //client退出时的事件
  client.on('close', () => {
    boardcast(client.id + " 下线了");
    delete clientlist[client.id];
  })
​
})
​
​
//广博通知,所有客户端
function boardcast(message) {
  for (let o in clientlist) {
    clientlist[o].send(message)
  }
}