HTTP通讯
WebSocket protocol 是HTML5一种新的协议,它实现了浏览器与服务器全双工通信(full-duple)。一开始的握手需要借助HTTP请求完成。
https://www.runoob.com/html/html5-websocket.html
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
WebSocket 实例
WebSocket 协议本质上是一个基于 TCP 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
以下 API 用于创建 WebSocket 对象。
var Socket = new WebSocket(url, [protocol] );
以上代码中的第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。
包的地址,及使用方法。
文档中的案例:
新建websocket文件夹,并用命令进入:
安装 websocket
在websocket文件夹中新建1.js
粘贴Server Example 代码
1.js
var WebSocketServer = require('websocket').server;
var http = require('http');
//创建服务器
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
//监听端口
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
//创建websocket服务器
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
//websocket 建立连接
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
//当前的连接
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
//监听当前连接 发送message时候
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
} else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
//监听当前连接 当close关闭 触发
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
新建前端界面,1.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>
</head>
<body>
<script>
//创建websocket对象
var ws = new WebSocket('ws://localhost:8080', 'echo-protocol');
//监听建立连接
ws.onopen = function(res) {
console.log("连接成功");
console.log(res);
}
//监听有新消息
ws.onmessage = function(res) {
console.log("有新消息");
console.log(res);
}
</script>
</body>
</html>
启动服务器:
用浏览器打开1.html
打开浏览器开发者工具,查看console
对1.js稍作更改:
添加定时器,发送消息。并重新启动1.js
var WebSocketServer = require('websocket').server;
var http = require('http');
//创建服务器
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
//监听端口
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
//创建websocket服务器
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
//websocket 建立连接
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
//当前的连接
var connection = request.accept('echo-protocol', request.origin);
setInterval(function() {
connection.sendUTF('服务端发送信息' + (new Date()));
}, 1000)
console.log((new Date()) + ' Connection accepted.');
//监听当前连接 发送message时候
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
} else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
//监听当前连接 当close关闭 触发
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
打开1.html
WebSocket多终端通讯
新建2.js
代码如下:
//多个终端 通过websocket进行通信
//参考websocket文档 https://github.com/theturtle32/WebSocket-Node/blob/HEAD/docs/index.md
//引入websocket server模块
var WebSocketServer = require('websocket').server
//引入http模块 搭建http服务器
var http = require('http');
var server = http.createServer();
server.listen(8080, function() {
console.log('服务搭建成功');
});
//创建websocket服务对象
var wsServer = new WebSocketServer({ httpServer: server });
//监听连接,建立连接
//webSocketRequest 当前的请求
wsServer.on('request', function(WebSocketRequest) {
//当前连接 回话
var connection = WebSocketRequest.accept('echo-protocol', 'accepted-origin');
//定时向客户端发送
setInterval(function() {
connection.sendUTF('hello world' + (new Date()));
//当前连接断开的时候,触发事件
connection.on('close', function(reasonCode, description) {
console.log('断开一个连接')
})
}, 1000)
});
运行2.js
打开1.html