Web Workers
什么是webworker?
Javascript
的运行模型属于单线程模型,即所有的代码都在主线程中执行,如果在Javascript
执行的过程中遇到了一些耗时任务(复杂运算),就会出现网页假死现象,而HTML5
标准中的WebWorker
为Javascript
提供了多线程异步执行任务的能力。
Web worker 是运行在后台的 JavaScript,不会影响页面的性能。
web worker使用限制
- 不能操作DOM,不能使用Document、Window、Parent这些对象。但是,可以使用navigator对象和location对象。
- 同源限制,worker脚本和主线程必须同源
- 不能alert、不能confirm,但是可以使用
ajax
(通常可以用来轮询后台数据) - 主线程和worker线程,不能直接通信,必须通过消息传递
Web Workers的分类
Web Workers根据工作环境的不同,可以分为Dedicated Worker
和Shared Worker
两种。
专用worker(Dedicated Worker
):只能从创建该Woker
的脚本中访问
共享worker(Shared Worker
):可以被多个脚本所访问
Web Workers的使用
1.主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。
let Worker = new Worker('worker.js');
2.onmessage
方法
worker.onmessage() 用于监听 线程之间 的消息,一旦其中一方 调用 postMessage 方法发送消息,则另一方可通过 onmessage() 方法监听到,然后通过 event.data 参数获取到另一方发送的消息;
worker.onmessage()处理函数允许我们在任何时刻,一旦接收到消息就可以执行一些代码,代码中消息本身作为事件的data属性进行使用;
3.postMessage
方法
worker.postMessage() 用于在线程之间发送消息;
4.terminate
方法
worker.terminate() 用于终止 worker,如果你需要从主线程中立刻终止一个运行中的worker,可以调用worker的terminate()
方法,worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
5.close
方法
而在worker线程中,workers 也可以调用自己的 close() 方法进行关闭
WebSocket
网络通信中的长连接与短连接
短连接:客户端请求与服务端建立网络连接,连接成功后,客户端向服务端发消息,服务端返回响应数据,客户端接收完毕后连接断开。
长连接:客户端请求与服务端建立网络连接,连接成功后,客户端向服务端发消息,服务端返回响应数据,完成一次通信后连接不断开。这个过程中双方都可以自发的向对方发消息。
HTTP协议属于短连接模式。因为短连接模式更加节省服务端资源,在不需要通信的时间段中可以将服务端有限的资源服务其他客户端。
而长连接有短连接做不到的功能:双方可以随时无差别向对方发消息。
Socket.io
socket.io
可以完成网页(客户端)中js
与后台nodejs
(服务端)之间的websocket
连接与数据通信。
基于websocket实现群聊功能:
1.建立WebSocket
连接
需要编写客户端html,以及服务端nodejs。
服务端
-
新建服务端项目目录。(新目录:
demo/socketserver
) -
进入项目目录,通过命令行初始化
npm
项目,安装socket.io
模块。npm init -y # 初始化npm项目, -y:所有问题都回答yes npm install --save socket.io
-
编写
index.js
文件,监听3000端口,接收客户端发过来的websocket
连接请求。连接建立成功后,基于socketio相关API实现客户端服务端通信。
node index.js
客户端
-
编写静态html网页, 引入
socket.io.js
。 -
执行代码,向服务端发送建立连接请求:
let socket = io('http://localhost:3000')
连接建立成功将会返回与服务端进行交互的
socket
对象。
2.基于建立好的连接,实现客户端服务端实时通信
连接一旦建立成功,服务端将会得到一个socket对象,客户端也将得到一个socket对象,二者就可以通过各自的socket对象向对方发消息,接收消息,实现通信。
客户端向服务端发消息
客户端发消息:
let socket = io('http://localhost:3000/')
// socket.emit(自定义消息类型, 消息内容)
socket.emit('textmsg', '你瞅啥~')
服务端接收消息:
socketio.on('connection', function(socket){
// 通过监听 textmsg 接收消息,接收到消息后,自动执行回调方法,将参数传入data
socket.on('textmsg', function(data){
console.log(data...)
})
})
服务端向客户端发消息
服务端发送消息
socketio.on('connection', function(socket){
// 调用socket.emit()方法即可向该客户端发消息
socket.emit('textmsg', '瞅你咋地~!')
})
客户端接收消息
let socket = io('http://localhost:3000/')
socket.on('textmsg', function(data){
alert(data)
})
服务端向所有客户端广播消息
这种方式将会把消息发给所有客户端,每个客户端都能收到消息:
socketio.on('connection', function(socket){
// socketio管理了所有的客户端, emit()方法将会给所有客户端发消息
socketio.emit('textmsg', '瞅你咋地~!')
})