使用SocketIO传图片
更新时间: 2024-11-25 11:25:31
之前实现了文字传输,现在提高一下难度传输图片,大致的思路如下:
- 在服务器上放一堆图片
- 读取图片列表,在客户端连上的时候将图片列表返回给客户端
- 客户端点击某个图片名称,就发送名称给服务端
- 服务端用fs模块获取到图片的二进制数据并发送给客户端
- 客户端接收到图片然后转码展示
先看一下效果吧
# 传输文件列表
使用fs模块:
const fileList = fs.readdirSync('./img')
1
然后在客户端连上的时候将fileList发出去:
const express = require('express')
const fs = require('fs')
const {createServer} = require('node:http')
const {Server} = require('socket.io')
const app = express()
const server = createServer(app)
const io = new Server(server,{
cors: {
origin: "*"
}
})
const fileList = fs.readdirSync('./img')
io.on('connection', (socket) => {
socket.emit('fileList', fileList)
})
server.listen(3000, () => {
console.log('server running at http://localhost:3000')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
然后客户端监听 fileList 事件,并保存:
const fileList = ref([])
socket = io("http://192.168.2.122:3000")
socket.on('fileList', (list) => {
fileList.value = list
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 向服务端发送要请求的图片
将fileList渲染成列表,点击列表项时,向socket发送select事件
<template>
<div class="main">
<ul class="img-ul">
<li v-for="item in fileList" @click="selectImg(item)">{{item}}</li>
</ul>
</div>
</template>
<script setup>
import {ref, onMounted} from "vue"
import {io} from "socket.io-client/dist/socket.io.js"
let socket = null
const fileList = ref([])
onMounted(() => {
socket = io("http://192.168.2.122:3000")
socket.on('fileList', (list) => {
console.log('fileList',list)
fileList.value = list
})
})
function selectImg(filename) {
socket.emit('select', filename)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 服务端返回图片数据
服务端监听select事件并读取对应的图片数据:
socket.on('select', (filename) => {
fs.readFile('./img/'+filename, (err, buf) => {
socket.emit('image', buf)
})
})
1
2
3
4
5
2
3
4
5
# 客户端解析收到的图片二进制数据
socket.on('image', (img, historyList) => {
const blob = new Blob([img])
history.value = historyList
imageSrc.value = URL.createObjectURL(blob)
})
1
2
3
4
5
2
3
4
5
# 完整代码
# 客户端
<template>
<div class="main">
<ul class="img-ul">
<li v-for="item in fileList" @click="selectImg(item)">{{item}}</li>
</ul>
<div class="img-wrapper">
<div>历史记录:{{history.join(',')}}</div>
<img class="img" :src="imageSrc" alt="">
</div>
</div>
</template>
<script setup>
import {ref, onMounted} from "vue"
import {io} from "socket.io-client/dist/socket.io.js"
let socket = null
const fileList = ref([])
const history = ref([])
const imageSrc = ref('')
onMounted(() => {
socket = io("http://192.168.2.122:3000")
socket.on('fileList', (list) => {
console.log('fileList',list)
fileList.value = list
})
socket.on('image', (img, historyList) => {
const blob = new Blob([img])
history.value = historyList
imageSrc.value = URL.createObjectURL(blob)
})
})
function selectImg(filename) {
socket.emit('select', filename)
}
</script>
<style scoped>
.main {
position: fixed;
top:0;
left:0;
right:0;
bottom:0;
display: flex;
}
.img-ul {
list-style: none;
padding:0;
margin:0;
background-color: brown;
width: 250px;
height:100%;
}
.img-ul li {
padding: 3px 7px;
cursor: pointer;
color: rgba(255,255,255,0.6);
}
.img-ul li:hover {
color: rgba(255,255,255,1);
}
.img-wrapper {
flex: 1;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 服务端
const express = require('express')
const fs = require('fs')
const {createServer} = require('node:http')
const {Server} = require('socket.io')
const app = express()
const server = createServer(app)
const io = new Server(server,{
cors: {
origin: "*"
}
})
const fileList = fs.readdirSync('./img')
io.on('connection', (socket) => {
const list = []
socket.emit('fileList', fileList)
socket.on('select', (filename) => {
list.push(filename)
fs.readFile('./img/'+filename, (err, buf) => {
socket.emit('image', buf, list)
})
})
})
server.listen(3000, () => {
console.log('server running at http://localhost:3000')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31