入门
nodeJS net模块 demo01
概述:
- TCP/IP 传输层协议,主要解决数据如何在网络中传输
- Socket 对Tcp/Ip协议的封装和应用
- Http 应用层协议,主要解决如何包装数据
- 网络五层模型 物理层,数据链路层,网络层,传输层,应用层
单向通信:
- 使用net单向通信
- 对比http通信
总结:
Socket是TCP/IP协议的封装,Socket本身不是协议,而是一个调用接口(API)。从而形成了我们知道的一些最基本的函数接口,比如create、listen、connect、accept、send、read、write等等。
TCP/IP是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,还要对外提供操作接口。
TCP双向通信 demo02
使用Socket实现Client
Server事件
- listening
- connection
- close
- error
Socket事件
- lookup
- connect
- data
- end
- timeout
- drain
- error
- close
基础聊天室服务器实现 demo03
- Tcp聊天室通信
- Node REPL (read-eval-print-loop),交互式解释器,类似Windows的cmd和Linux的shell,允许我们在终端输入命令,并获取系统的响应
- 趣味小程序 console Chat
socket.io入门 demo04
什么是Socket.io
- 是一个node package
- 是node下的实时应用应用程序框架
如何使用Socket.io
- 安装
npm install socket.io --save
- 监听端口
- 客户端连接
服务器端的两种实现方式:
const server = io(); server.listen(PORT);
const server = io(httpServer);httpServer.listen(PORT);
socket.io基本框架 demo05
- 创建项目
- express & koa
- 前端构建 (gulp 实现服务自动重启&启动)
- 在express中使用socket.io
socket.io自定义事件
- socket.io用户认证
- socket.io-client 连接,重连,断开,配置
- 跨浏览器的websocket socket.send(data) -> client.on('message', data => {})
- socket事件通信 emit -> on
消息广播与私聊
聊天室UI
- bootstrap UI
消息广播
- io.emit 发送给全部客户端
- io.sockets.emit() 发送给全部客户端
- io.broadcast.emit() 发送给除了自己的客户端
- for of遍历
私聊
- socket.emit 当前客户端
基于socket.io的聊天服务器搭建
聊天室功能
- 设置客户端昵称
- 上线通知
- 离线通知
- 群聊
- 私聊
- 在线列表更新
进阶
Base64图片传输
- 图片传输(粘贴图片)
- 通过canvas(远程文件)
- 通过FileReader(本地文件)
// 监听'paste'事件,将图片进行base64编码,发送到服务器
$(document).on('paste', e => {
// 获取剪切板上的数据
let originalEvent = e.originalEvent;
let items;
if (originalEvent.clipboardData && originalEvent.clipboardData.items) {
items = originalEvent.clipboardData.items;
}
if (items) {
// 读取文件数据
for (let i = 0, len = items.length; i < len; i ++) {
let item = items[i];
if (item.kind === 'file') {
let pasteFile = item.getAsFile();
if (pasteFile.size > 1024 * 1024) {
return;
}
let reader = new FileReader();
// 读取结束发送
reader.onloadend = function() {
let base64Str = reader.result;
sendMsg(base64Str, 'image');
}
// 异步读取文件
reader.readAsDataURL(pasteFile);
}
}
}
});
总结:监听粘贴事件,将文件进行base64编码,编码结束后的操作和普通消息的操作相同
Binary数据传输
- 上传文件UI 遮罩
- 发送文件
- 文件接收
socket.io命名空间划分
命名空间与Room
- 命名空间包含多个Room
命名空间的使用
- 默认命名空间
- 创建命名空间
// 服务端创建新的命名空间
let newNsp = io.of('/nsp1');
newNsp.on('connection', socket => {
socket.emit('online', 'nsp1');
});
// 客户端连接命名空间
let clientForNsp1 = io.connect('http://localhost:8001/nsp1');
clientForNsp1.on('online', data => {
console.log(data);
});
// 不同命名空间访问
newNsp.on('server.test', data => {
io.emit('client.test', data);
});
聊天室房间划分
socke.io的房间
加入房间
- socket.join(roomName);
离开房间
- socket.leave(roomName);
房间内发消息
- io.to(roomName).emit(eventName, data);
- socket.broadcast.to(roomName).emit(eventName, data);
默认房间
- socket.adapter.rooms 默认房间名是socket.id,这也是私聊的实现原理。socket.to(SocketId).emit(eventName, data);
QQ群的实现原理
新建一个群等于创建一个房间,生成房间号并保存到服务器上。用户上线时,遍历用户参加的房间号,然后将用户加入到这些房间中,只要有群消息,用户就能收到
高级
消息推送介绍
什么是消息推送
消息推送,也叫‘信息推送’,术语叫‘web广播’。是通过一定的技术标准或者协议,在网络上定期传送数据来减少信息过载的一项技术。
案例:在开发Andriod和Ios应用时,服务器会不定时的向手机客户端及时推送各种通知消息,这种场景就使用及时推送。应用在物联网,手机App上。
推送方案评价标准
- 安全
- 稳定
- 节省
- 体积小
学生网
消息推送方式
- Http推送 轮询(polling)、长连接(comet)、websocket
- Xmpp推送
- Sms拦截
- Sqtt
MQTT基本介绍mqtt-demo
关于MQTT
(Message Queuing Telemetry Transport)消息队列遥测传输,IBM开发的一个及时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物体和外部链接起来,被用来当做传感器和致动器。
MQTT特点
- 使用发布订阅消息模式,提供一对多的消息发布,解除应用程序耦合
- 对负载内容屏蔽的消息传输
- 使用TCP/IP提供网络连接
- 三种消息发布质量 至多一次,只有一次,至少一次
- 小型传输,开销小(固定长度的头部是2字节),协议交换最小化,以降低网络流量
- 使用last Will和testament特性,通知有关客户端异常中断的机制
相关网站
Node中使用
MQTT服务搭建
mosca
- mosca是MQTT的一个代理,这意味着它实现了MQTT协议,我们就可以在node上运行MQTT Server
- 官网
npm install mosca --save
- 虽然是MQTT代理,本身不具有集群功能,如果要扩展它,还需要借助第三方库,如Redis、MongoDb、RabbitMQ、ActiveMQ、ZeroMQ等
mosca Events
- ready 服务端准备完成
- error 服务端发生错误
- published 发布数据后
- subscribed 客户端订阅后
- unsubscribed 客户端取消订阅后
- clientConnected 客户端连接成功后
- clientDisconnected 客户端断开连接后
MQTT协议解读
基本术语
- 网络连接
- 客户端使用它连接服务器,提供有序的、可靠地、双向字节流传输
- 应用消息
- 服务质量、主题
- 客户端
- 发布特定消息给相关客户端
- 订阅以请求接受相关应用消息
- 取消订阅移除接受订阅消息的请求
- 从服务端断开连接
- 服务端
- 接受来自客户端的网络连接
- 接受客户端发布的应用消息
- 处理客户端订阅和取消订阅的请求
- 转发应用消息给符合条件的客户端订阅
- 订阅
- 主题名
- 主题过滤器
- 会话
- 控制报文
控制报文
- 连接服务端
- 确认连接请求
- 发布消息
- 发布确认
- 发布收到
- 发布释放
- 发布完成
- 订阅主题
- 订阅确认
- 取消订阅
- 取消订阅确认
- 心跳请求
- 心跳响应
- 断开连接
服务质量Qos
- QoS 0: 至多分发一次
- Qos 1: 至少分发一次
- Qos 2: 仅分发一次
主题&主题过滤器
- 主题通配符
- 主题层级分隔符
- 多层通配符
- 单层通配符
- 以$开头的主题
- 主题名和主题过滤器规则
- 至少包含一个字符
- 区分大小写
- 可包含空格
- 以'/'进行分割
- 只包含'/'是合法的
- 不能包含空白字符
- UTF-8编码字符串,65535个字符
基于Node客户端实现
- mqtt.js
- mqtt.js in node
- mqtt.js in browser
主题树
什么是主题树 将信息资源按照某种事先确定的体系,分门别类的逐层加以组织
MQTT里的主题树
const client = mqtt.connect('mqtt://localhost:7410');
client.on('connect', () => {
client.subscribe('/node1/node2/node3'); // 订阅不到
client.subscribe('/node1/node2/+'); // 订阅不到 +至多一层
client.subscribe('/node1/node2/#'); // 能够订阅 #为通配符
client.publish('/node1/node2/node3/node4', 'test1');
});
client.on('message', (topic, message) => {
console.log(topic,' ', message.toString());
});
主题树的作用
- 提供了有层级的主题
- 通过锁定主题树,确保用户能够访问他们要访问的信息
访问控制列表ACL
什么是ACL
- 全称(Access Control List),访问控制列表
- mosca基于用户的访问控制
权限监控
mosca.Authorizer()
addUser(user, pass, authorizePublish, authorizeSuscribe, cb)
rmUser(user, cb)
mosca重写以下三个方法
- authenticate(client, username, password, callback)
- authorizePublish(client, topic, payload, callback)
- authorizeSuscribe(client, topic, callback)
性能测试和分析
- mosca JavaScript小规模 学习使用
- Musquitto c语言
- emqttd Erlang语言 峰值100w连接数 适合企业级
- Moquette java语言 适合企业级