socket.io
主要是解決輪詢帶來的資源浪費,通過長連接,主要以事件註冊(socket.on)和事件觸發(socket.emit)通信
官網上有簡單的demo:
//server.js
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){ //建立連接時觸發
console.log('a user connected');
socket.on('disconnect', function(){ //斷開連接時觸發
console.log('user disconnected');
});
socket.on('chat message', function(msg){ //定義server事件,由client觸發
io.emit('chat message', msg); //觸發cliet事件
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
//client.js
<script>
$(function () {
var socket = io();
$('form').submit(function(e){
e.preventDefault(); // prevents page reloading
socket.emit('chat message', $('#m').val()); //觸發server事件
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){ //定義client事件
$('#messages').append($('<li>').text(msg));
});
});
</script>
以上demo是消息的發送,下面介紹兩種圖片的發送
1、使用FileReader把圖片文件轉成base64,當作信息發送到server,再由server分發到其他client
//client.js
$('#pic').change((e) => {
const file = e.target.files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function() {
socket.emit('sendTu', { img: this.result }) //this.result :base64發送到server
}
}
//server.js
socket.on('sendTu', msg => { //接收base64
msg.id = socket.id
socket.emit('renderTu', msg) //分發給自己
socket.broadcast.emit('renderTu', msg) //分發到其他client
})
2、使用ajax發送文件到server,再由server分發圖片地址,使用到FormData
//client.js
const post = (url, data, cb) => {
const req =new XMLHttpRequest()
req.open('POST', url, true)
req.send(data)
req.onreadystatechange = () => {
if(req.readyState == 4) {
if((req.status >= 200 && req.status < 300) || req.status == 304) {
console.log('succeess', req.responseText)
typeof cb === 'function' && cb(req.responseText)
}
}
}
}
$('#pic').change((e) => {
const file = e.target.files[0]
const formData = new FormData()
formData.append(file.name, file)
post('/sendPic', formData, res => {
const data = JSON.parse(res)
socket.emit('sendTu', { img: data.path }) //接收到路徑,通知server進行分發地址
})
}
//server.js //需要用到formidable模塊,npm安裝即可
app.use(express.static(__dirname + '/static')) //設置static爲靜態文件目錄
app.post('/sendPic', (req, res) => {
console.log('sendPic')
let imgname = null;
let form = new formidable.IncomingForm();
form.uploadDir = './static/images'; //保存到static/images目錄下
form.parse(req, (err, fields, files) => {
res.send(imgname); //存儲成功把路徑返回
});
form.on('fileBegin', (name, file) => {
file.path = path.join(__dirname, `./static/images/${file.name}`);
imgname = { name: file.name, path: `/images/${file.name}` };
})
})