### koa-socket
#### 核心思想socket-io
- 轮询ajax 缺点:不停询问服务器,浪费性能
- 服务器不关闭连接,一次响应,一直保持连接 缺点:只有服务器向客户端不断输出
- html5中出来了一个websocket 他是在原来http协议的基础上,去升级当前协议为websocket升级
- 将原本 先有请求才有响应的机制,更改成了,服务端也可以主动发请求给客户端
- HTTP 一问一答, TCP协议,客户端与服务器建立连接以后,就可以自由的通信了
- 缺点:有兼容性问题(IE11)
- socket.io交互方式可能通过websocket/轮询ajax/服务器响应流(保持连接)
- 1. 服务器可主动发数据到客户端
\2. 客户端向客户端发数据通过服务器
<html>
<head>
<meta charset="UTF-8">
<title>01_长轮询</title>
</head>
<body>
<input type="text" name="" id="time">
<script type="text/javascript" src="/jquery.js"></script>
<script type="text/javascript">
//长轮询的方式,通过浏览器频繁发送请求来更新数据
setInterval(function(){
$.ajax({
type:'get',
url:'/getTimerByLongPull',
// dataType:'json',
success:function(time){
$('#time').val(time);
}
});
},1000);
</script>
</body>
</html>
<html>
<head>
<meta charset="UTF-8">
<title>02_长连接</title>
</head>
<body>
<input type="text" name="" id="time">
<script type="text/javascript" src="/jquery.js"></script>
<script type="text/javascript">
//长连接的方式,通过一次请求,服务器保持住连接,在连接超时前响应用户
var xhr = new XMLHttpRequest();
xhr.open('get','/getTimeByLongConn');
xhr.onreadystatechange = function(res){
//xhr.readyState===3服务器会给上一个头信息,但是数据没有发送完毕
if(xhr.readyState === 3){
console.log(xhr.responseText);
}
}
xhr.send();
//HTML5中的eventSource来单向推数据
var es = new EventSource('/getTimeByLongConn');
es.onmessage = function(e){
document.querySelector('#time').value = e.data;
}
//关闭该事件源
//es.close();
</script>
</body>
</html>
<html>
<head>
<meta charset="UTF-8">
<title>03_websocket</title>
</head>
<body>
<input type="text" name="" id="time">
<script type="text/javascript" src="/jquery.js"></script>
<script type="text/javascript">
//使用websocket的方式实现即时双向通信
var ws = new WebSocket('ws://127.0.0.1:8080');//参数为请求地址和url
ws.onopen = function(event){//设置连接打开的操作
ws.send('我连接上了');
};
ws.onmessage = function(event){
document.getElementById('time').value = event.data;
};
ws.onclose = function(event){
//关闭的操作
}
// ws.close();
</script>
</body>
</html>
app.js
'use strict';
const http = require('http');
const fs = require('fs');
//getTimeByLongConn
let server = http.createServer(function(req, res) {
if (req.url === '/1') { //响应长轮询的页面
fs.readFile('./01_long_pull.html', (err, data) => {
res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' });
return res.end(data);
});
} else if (req.url === '/2') { //响应长轮询的页面
fs.readFile('./02_long_conn.html', (err, data) => {
res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' });
return res.end(data);
});
} else if (req.url === '/3') { //响应长轮询的页面
fs.readFile('./03_ws.html', (err, data) => {
res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' });
return res.end(data);
});
} else if (req.url === '/jquery.js') { //处理静态资源
fs.readFile('./jquery.js', (err, data) => {
res.writeHead(200, { 'content-type': 'application/x-javascript;charset=utf-8' });
return res.end(data);
});
} else if (req.url === '/getTimerByLongPull') { //处理长轮询
res.end(Date.now() + '');
} else if (req.url === '/getTimeByLongConn') { //处理长连接不要end
res.writeHead(200, { 'content-type': 'text/event-stream' }); //达到每次传输部分数据的效果
setInterval(function() {
// res.write(Date.now() + ''); 原生ajax使用方式
// eventSouce 使用方式
res.write('data:' + Date.now() + '\n\n')
}, 1000);
} else {
return res.end('icon'); //处理图标
}
});
server.listen(80, '127.0.0.1', function() {
console.log('服务器启动了');
});
//启动websocket服务器
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 8080 });
wss.on('connection', function(ws) {
//ws 就是一个websocket对象,里边可以发送和接受数据,
ws.on('message', function(message) {
console.log('received: ' + message);
});
setInterval(function() {
ws.send(Date.now() + '');
}, 1000);
});