镇楼图

Pixiv:torino

因为最近在做一个有实时功能的小项目需要websocket,因此记录此次学习的内容(JS还没学完的说),但其实是非常简单的因为不涉及原理拿来用就行

本篇文章涉及到少量node、服务器开发的内容



一、客户端WebSocket

因为http只能来回单向的通信,若要强行实现只能通过Ajax轮询方式来变相实现双向的通信但消耗很大。而websocket则能够实现客户端、服务端双向的通信(具体原理在RFC6455)

在Web API中有客户端的WebSocket的API可以直接拿来用

创建WebSocket实例

当创建对象实例时即去请求服务端建立ws协议下的通信

const socket = new WebSocket("ws://localhost:1600");
//尝试与本地1600端口号进行ws通信
//若失败则抛出SECURITY_ERR异常
构造器 说明
WebSocket(url,[proto]) url指定WS服务器的url,proto可选用来指定ws协议下的子协议(也可以为数组)
其中url必须是ws协议下的

方法

方法 说明
close([code],[reason]) 由客户端发起的主动断开连接
其中可以选择code说明断开的状态码以及reason说明原因
状态码默认使用1005
原因为UTF-8字符串但不能超过123字节
send(data) 向服务端发送数据
其中数据必须是UTF-8字符串,Blob,ArrayBuffer或ArrayBufferView
socket.send("123456789");
//发送数据
//若socket未连接则抛出INVALID_STATE_ERR异常
socket.close(1005,"断开连接");
//若code错误则抛出INVALID_ACCESS_ERR异常
//若原因超出123字节则抛出SYNTAX_ERR异常

只要通过send就能完成数据的传输,但传输只接受字符串或是二进制数据,因此需要转换下某些内容的数据格式

属性

属性 说明
url 只读,返回WebSocket实例连接服务端的url字符串(UTF-16)
readyState 只读,返回WebSocket实例当前的连接状态,有如下固定值
WebSocket.CONNECTIING:0正在连接中
WebSocket.OPEN:1连接成功
WebSocket.CLOSING:2正在关闭连接
WebSocket.CLOSED:3未连接
protocol 只读,返回连接子协议的字符串数组(UTF-16)
extensions 只读,返回服务端返回的扩展值
binaryType 返回连接传输的二进制数据类型
分为blob类型和arraybuffer两种类型
console.log(socket.url);
console.log(socket.protocol);
console.log(socket.readyState);

事件

WebSocket总共有4个事件,也是非常简单的

事件 说明
open(onopen) 当实例状态转变OPEN状态时调用
close(onclose) 当实例状态转变CLOSED状态时调用
error(onerror) 当实例的连接出错时调用,继承CloseEvent接口
message(onmessage) 当实例接受到服务端消息时调用,继承MessageEvent接口

send方法具体过程

当使用send方法后并不是简单地直接发送给服务端,它会先将数据排队进入缓存,然后从缓存内发送数据。此外如果缓存区已满则会自动关闭连接

bufferedAmount是一个只读属性,可以返回目前缓存区数据的总大小(单位:字节)即每次send后bufferedAmount会先增大,如果缓存区再发送给服务端数据成功则会减少bufferedAmount,发送完成后即bufferedAmount=0

此外send过程中连接断开了,则缓存区的内容会被保留即bufferedAmount不会归零

CloseEvent

当连接状态转为CLOSED时便会创建CloseEvent对象,可以通过close(onclose)来监听此创建事件

属性 说明
code 只读,关闭事件的状态码,不同状态码会有不同含义具体参考MDN
reason 只读,关闭事件的原因(UTF-8字符串)
wasClean 只读,布尔值,连接是否完全关闭

可以监听的时候获取该对象

socket.onclose = function(e){
    console.log("连接断开原因:"+e.reason);
}

MessageEvent

当客户端接收到数据时便会创建MessageEvent对象,可以通过message(onmessage)来监听此创建事件

除了WebSocket其他接口用了该对象区表述消息事件,其中最重要的是data属性,里面包含了服务端发来的数据

socket.onmessage = function(e){
	console.log(`服务端发来的数据是:${e.data}`);
}

二、服务端nodejs-websocket

服务端有很多不同的服务端websocket,这里只说明nodejs-websocket(一是因为教程用了此js,另一方面是对比其他属于特别简单的了)

这里仅涉及服务端相关功能(且忽略子协议相关内容因为涉及到了原理),不会说明客户端,具体可查看该项目的文档

//官方案例
var ws = require("nodejs-websocket")

// 服务端功能例子: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
	console.log("New connection")
	conn.on("text", function (str) {
		console.log("Received "+str)
		conn.sendText(str.toUpperCase()+"!!!")
		//转换成大写并附加!!!返回给客户端
	})
	conn.on("close", function (code, reason) {
		console.log("Connection closed")
	})
}).listen(8001)

说明
ws 参考案例,通过require创建该对象
server 服务器类,可以通过ws的createServer方法创建
connection 连接类,可以通过ws或server某些方法创建主要用于接发数据
其中数据分成Text字符串和Binary二进制两种数据格式

事件

在nodejs-websocket中事件具有参数,且部分是触发某些方法后才会触发的事件

server类事件 触发条件
listening() 执行server.listen方法时触发
close() 执行server.close方法时触发
errpr(errObj) 错误时触发
connection(conn) 连接成功后触发
connection类事件 触发条件
close(code,reason) 当连接被关闭时触发
error(err) 错误时触发
text(str) 从客户端接收到text时触发

常用方法

常用方法 说明
ws.createServer([options],[callback]) 创建Server实例
其中callback是指调用该方法后所调用的函数
srever.listen(port,[host],[callback]) server监听port端口
其中host是指可接收客户端的IP地址,省略则默认接收任意IP地址的客户端
server.close([callback]) 停止服务器接受新的连接
connection.sendText(str,[callback])
connection.send(str,[callback])
向当前连接的客户端发送字符串消息
connection.close(code,[reason]) 关闭连接
常用属性 说明
server.connections 包含当前server所有客户端请求的connection数组
适用于实现多个发送消息时使用
connection.readyState 查看连接状态即之前客户端那里的那四个
connection.server 返回当前连接的server


参考文档

MDN Websocket

nodejs-websocket

posted on 2022-05-27 14:40  摸鱼鱼的尛善  阅读(81)  评论(0编辑  收藏  举报