WebSocket
WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持。
WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。
Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。
ajax轮询
客户端:啦啦啦,有没有新信息(Request)
服务端:没有(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:没有。。(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:你好烦啊,没有啊。。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:好啦好啦,有啦给你。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:。。。。。没。。。。没。。。没有(Response) —- loop
WebSocket
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈
socket.io
node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。Socket.io将Websocket和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。也就是说,Websocket仅仅是 Socket.io实现实时通信的一个子集。那么,Socket.io都实现了Polling中的那些通信机制呢?
- Adobe® Flash® Socket
- AJAX long polling
- AJAX multipart streaming
- Forever Iframe
- JSONP Polling
使用socket.io制作聊天室
-
初始化
package.json
文件
在项目文件夹主目录下执行以下命令$ cnpm init -y
-
安装对应的包
-
express
服务器端路由的制作$ cnpm install --save express
-
socket.io
WebScoket的封装库$ cnpm install --save socket.io
-
-
编写
server.js
服务器文件
创建server.js文件,作为服务器,使用express模块进行路由的编写// 引入对应的模块 var app = require('express')(); var http = require('http').Server(app); // 访问首页即访问index.html文件 app.get('/', function(req, res) { res.sendfile(__dirname + '/index.html'); }); // 设置端口以及回调 http.listen(8888, function() { console.log('listening on *:3000'); });
-
编写
index.html
文件<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title></title> <style media="screen"> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; } #messages { list-style-type: none; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } form { position: fixed; left: 0; right: 0; bottom: 0; height: 50px; background-color: #333; } form input { width: 80%; height: 40px; margin-top: 5px; border: none; } form button { width: 18%; height: 100%; background-color: cyan; border: none; } </style> </head> <body> <div class="container"> <ul id="messages"></ul> <form action=""> <input id="m" type="text" name="" value=""> <button type="submit">Send</button> </form> </div> </body> </html>
-
在终端执行
node server.js
命令,即可运行服务器,打开浏览器输入http://localhost:8888
,即可看到效果 -
在
server.js
中添加代码,进行socket.io
的数据传输事件的注册,并重启服务// 引入对应的模块 var app = require('express')(); var http = require('http').Server(app); // 新增代码++++++++++++++++++++++++++ // 引入socket.io模块 var io = require('socket.io')(http); // 访问首页即访问index.html文件 app.get('/', function(req, res) { res.sendFile(__dirname + '/index.html'); }); // 新增代码++++++++++++++++++++++++++ // 注册事件,连接成功即可执行 io.on('connection', function (socket) { console.log('链接已成功'); // 注册事件,连接断开即可执行 io.on('disconnection', function (socket) { console.log('链接已断开'); }); }); // 设置端口以及回调 http.listen(8888, function() { console.log('listening on *:3000'); });
-
在
index.html
中添加代码,创建一个socket
对象,即可触发server.js
中注册的事件<script src="/socket.io/socket.io.js"></script> <script type="text/javascript"> var socket = io(); </script>
刷新网页的时候,即可看到如下的输出结果:
lidaze-MBP-2:chat-room lidaze$ node server.js listening on *:3000 链接已成功 链接已断开 链接已成功 链接已断开 链接已成功
-
继续
index.html
文件代码的编写<script src="/socket.io/socket.io.js"></script> <script src="https://code.jquery.com/jquery-1.11.1.js"></script> <script type="text/javascript"> $(function () { // 创建socket对象 var socket = io(); // 设置表单提交事件 $('form').submit(function () { // 使用socket触发事件,通过传参的方式将数据传递给服务器 socket.emit('chat message to server', $('#m').val()); $('#m').val(''); return false; }); }); </script>
-
当点击网页中的发送按钮时,会触发socket触发事件,进行数据的传递,同样的,也需要在服务器端进行事件的监听
在server.js
中添加如下代码,进行数据的获取// 注册事件,连接成功即可执行 io.on('connection', function (socket) { console.log('链接已成功'); // 新增代码++++++++++++++++++++++++++ // 用于接收数据的监听 socket.on('chat message to server', function (msg) { console.log('message: ' + msg); }); // 注册事件,连接断开即可执行 socket.on('disconnect', function (socket) { console.log('链接已断开'); }); });
重启服务器,在网页中输入内容,然后点击发送按钮,即可看到控制台中有内容输出
-
现在已经实现了前端向后台发送数据,下面来实现服务器向浏览器返回数据。并重启服务
// 用于接收数据的监听
socket.on('chat message to server', function (msg) {
console.log('message: ' + msg);
// 新增代码++++++++++++++++++++++++++
// 使用io对象进行事件的触发,将数据从服务器发送到浏览器
io.emit('chat message to browser', msg);
});
-
在
index.html
中接收服务器返回的数据// 注册事件,用于接收浏览器返回的数据 socket.on('chat message to browser', function (msg) { // 接收到数据后创建li标签,并拼接到页面中 $('#messages').append($('<li>').text(msg)); });
-
代码至此已经编写完毕,使用浏览器打开两个网页,均访问
http://localhost:8888
地址,在一张网页中输入内容,即可发现在另一个网页中效果同步。这就是借助了WebSocket的及时通讯。除了实现浏览器端向服务器端发送数据外,服务器端也可以同时发送数据到浏览器中.