# 前后端通信
## 1、websocket
`websocket :长连接,双向的。node搭建的websocket服务器,推送信息给客户端浏览器`
* 前端
```html
<!-- websocket.html -->
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock')
let socket = new WebSocket('ws://localhost:9999')
//当连接成功之后就会执行回调函数
socket.onopen = function() {
console.log('客户端连接成功')
//再向服务 器发送一个消息
socket.send('hello') //客户端发的消息内容 为hello
}
//绑定事件是用加属性的方式
socket.onmessage = function(event) {
clockDiv.innerHTML = event.data
console.log('收到服务器端的响应', event.data)
}
window.onload=function(){
clockDiv.addEventListener('click',()=>{
socket.send('clockDiv点击事件')
})
}
</script>
```
* 后端
```js
// websocket.js
/**
* 依赖包
* npm i express ws -S
*/
let express = require('express')
let app = express()
app.use(express.static(__dirname))
//http服务器
app.listen(3000)
let WebSocketServer = require('ws').Server
//用ws模块启动一个websocket服务器,监听了9999端口
let wsServer = new WebSocketServer({ port: 9999 })
//监听客户端的连接请求 当客户端连接服务器的时候,就会触发connection事件
//socket代表一个客户端,不是所有客户端共享的,而是每个客户端都有一个socket
wsServer.on('connection', function(socket) {
//每一个socket都有一个唯一的ID属性
console.log(socket)
console.log('客户端连接成功')
//监听对方发过来的消息
socket.on('message', function(message) {
console.log('接收到客户端的消息', message)
socket.send('服务器回应:' + message)
})
setTimeout(()=>{
socket.send('内容更新了:')
},5000)
})
```
## 2、Server-Sent Events(简称SSE)/EventSource
`只是从服务器端往客户端单向传输数据,感觉就隔几秒发送一个get请求获取数据`
* 前端
```html
<!-- sse.html -->
<div id="clok"></div>
<script type="text/javascript">
if ('EventSource' in window) {
var source = new EventSource('http://127.0.0.1:8844/stream');
var sseEl = document.getElementById('clok');
source.addEventListener('open', function (event) {
sseEl.innerHTML += '<p>Connection open ...</p>';
}, false);
source.addEventListener('message', function (event) {
sseEl.innerHTML += ('<p>Ping: ' + event.data + '</p>');
}, false);
source.addEventListener('error', function (event) {
sseEl.innerHTML += '<p>Connection close.</p>';
}, false);
source.addEventListener('connecttime', function (event) {
sseEl.innerHTML += ('<p>Start time: ' + event.data + '</p>');
}, false);
// source.close();
source.addEventListener('foo', function (event) {
var data = event.data;
// handle message
}, false);
}
</script>
```
* 后端
```js
// sse.js
/**
* 依赖包 npm i http -S
*/
var http = require("http");
http.createServer(function (req, res) {
var fileName = "." + req.url;
if (fileName === "./stream") {
res.writeHead(200, {
"Content-Type":"text/event-stream",
"Cache-Control":"no-cache",
"Connection":"keep-alive",
"Access-Control-Allow-Origin": '*',
});
res.write("retry: 10000\n");
res.write("event: connecttime\n");
res.write(`data: ${(new Date())}\n\n`);
res.write(`data: ${(new Date())}\n\n`);
interval = setInterval(function () {
res.write(`data:数据内容更新了1\n\n`);
}, 1000);
req.connection.addListener("close", function () {
clearInterval(interval);
}, false);
}
}).listen(8844, "127.0.0.1");
```
## 3、
> 参考资料
* [Web 实时推送技术的总结](https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651556073&idx=1&sn=7009b6f2c95e3e48254964f43e838d9b&chksm=80255f28b752d63e89e5e96b3d462ea025bb7a4cc03783e5c8f8c86fcfdcb51b8d3c901035b8&mpshare=1&scene=1&srcid=#rd)
* [Server-Sent Events 教程](http://www.ruanyifeng.com/blog/2017/05/server-sent_events.html)