DEBUG
This commit is contained in:
		@@ -3,6 +3,8 @@ webrtc 实现的 p2p 信道
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [x] P2P通信
 | 
					- [x] P2P通信
 | 
				
			||||||
  - [ ] 分离出主要功能, 作为库或桁架使用
 | 
					  - [ ] 分离出主要功能, 作为库或桁架使用
 | 
				
			||||||
 | 
					  - [ ] 静态资源服务模式
 | 
				
			||||||
 | 
					  - [ ] 集群分发
 | 
				
			||||||
- [x] 音乐播放
 | 
					- [x] 音乐播放
 | 
				
			||||||
  - [x] 请求到单个目标防止接收到重复分片数据
 | 
					  - [x] 请求到单个目标防止接收到重复分片数据
 | 
				
			||||||
    - [x] 主机记录各自曲目列表以供查询
 | 
					    - [x] 主机记录各自曲目列表以供查询
 | 
				
			||||||
@@ -20,9 +22,10 @@ webrtc 实现的 p2p 信道
 | 
				
			|||||||
  - [ ] 分片播放时支持flac
 | 
					  - [ ] 分片播放时支持flac
 | 
				
			||||||
  - [ ] 取消本地存储时检查是否移除(其它成员可能有同一曲)
 | 
					  - [ ] 取消本地存储时检查是否移除(其它成员可能有同一曲)
 | 
				
			||||||
  - [ ] 成员列表刷新时播放被重置BUG
 | 
					  - [ ] 成员列表刷新时播放被重置BUG
 | 
				
			||||||
- [ ] 集群分发
 | 
					  - [ ] 削弱刷新带来的影响
 | 
				
			||||||
- [ ] 下载加速
 | 
					- [ ] 下载加速
 | 
				
			||||||
- [ ] 即时通讯
 | 
					- [ ] 即时通讯
 | 
				
			||||||
 | 
					- [ ] 画廊
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- 能获取所有在线设备列表
 | 
					- 能获取所有在线设备列表
 | 
				
			||||||
- 随机连接至四个设备, 且按效率扩展收缩
 | 
					- 随机连接至四个设备, 且按效率扩展收缩
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -208,6 +208,12 @@ export default class ClientList {
 | 
				
			|||||||
        const avatar = localStorage.getItem('avatar')
 | 
					        const avatar = localStorage.getItem('avatar')
 | 
				
			||||||
        this.add({ id: 'self', name: username, avatar })
 | 
					        this.add({ id: 'self', name: username, avatar })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    getAvatar(id) { }
 | 
				
			||||||
 | 
					    setAvatar(user) {
 | 
				
			||||||
 | 
					        console.log('更新avatar', user)
 | 
				
			||||||
 | 
					        document.getElementById(user.id).querySelector('img').src = user.avatar
 | 
				
			||||||
 | 
					        this.clientlist.find(client => client.id === user.id).avatar = user.avatar
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    exit(item) {
 | 
					    exit(item) {
 | 
				
			||||||
        const client = this.clientlist.find(client => client.id === item.id)
 | 
					        const client = this.clientlist.find(client => client.id === item.id)
 | 
				
			||||||
        if (!client) return console.log('目标用户本不存在')
 | 
					        if (!client) return console.log('目标用户本不存在')
 | 
				
			||||||
@@ -219,7 +225,6 @@ export default class ClientList {
 | 
				
			|||||||
        this.channels[name] = option
 | 
					        this.channels[name] = option
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    add(item) {
 | 
					    add(item) {
 | 
				
			||||||
        console.log(item)
 | 
					 | 
				
			||||||
        this.element.appendChild(ListItem({
 | 
					        this.element.appendChild(ListItem({
 | 
				
			||||||
            id: item.id,
 | 
					            id: item.id,
 | 
				
			||||||
            onclick: event => {
 | 
					            onclick: event => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // 读取本地用户名(本地缓存)
 | 
					        // 读取本地用户名(本地缓存)
 | 
				
			||||||
        const name = localStorage.getItem('username') ?? '游客'
 | 
					        const name = localStorage.getItem('username') ?? '游客'
 | 
				
			||||||
 | 
					        const avatar = localStorage.getItem('avatar') ?? '/favicon.ico'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 初始化客户端列表
 | 
					        // 初始化客户端列表
 | 
				
			||||||
        const clientList = new ClientList({
 | 
					        const clientList = new ClientList({
 | 
				
			||||||
@@ -46,7 +47,7 @@
 | 
				
			|||||||
                console.log(client.name, '离开频道', client)
 | 
					                console.log(client.name, '离开频道', client)
 | 
				
			||||||
                // 从列表中移除未缓存的此用户的音乐, 但可能多人都有此音乐且未缓存
 | 
					                // 从列表中移除未缓存的此用户的音乐, 但可能多人都有此音乐且未缓存
 | 
				
			||||||
                // 因此每条音乐都要检查是否有其他用户也有此音乐, 如果有则不移除
 | 
					                // 因此每条音乐都要检查是否有其他用户也有此音乐, 如果有则不移除
 | 
				
			||||||
                const 此用户音乐 = client.musicList.map(item => item.id)
 | 
					                const 此用户音乐 = client.musicList?.map(item => item.id) || []
 | 
				
			||||||
                const 无数据音乐 = musicList.list.filter(item => !item.arrayBuffer).filter(item => {
 | 
					                const 无数据音乐 = musicList.list.filter(item => !item.arrayBuffer).filter(item => {
 | 
				
			||||||
                    return 此用户音乐.includes(item.id)
 | 
					                    return 此用户音乐.includes(item.id)
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
@@ -150,10 +151,31 @@
 | 
				
			|||||||
                console.log('打开信道', event.target.label)
 | 
					                console.log('打开信道', event.target.label)
 | 
				
			||||||
                // 要求对方发送音乐列表
 | 
					                // 要求对方发送音乐列表
 | 
				
			||||||
                clientList.send('base', JSON.stringify({ type: 'get_music_list' }))
 | 
					                clientList.send('base', JSON.stringify({ type: 'get_music_list' }))
 | 
				
			||||||
 | 
					                // 要求对方发送身份信息
 | 
				
			||||||
 | 
					                clientList.send('base', JSON.stringify({ type: 'get_user_profile' }))
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            onmessage: async (event, client) => {
 | 
					            onmessage: async (event, client) => {
 | 
				
			||||||
                const { type, id, channel, list } = JSON.parse(event.data)
 | 
					                const data = JSON.parse(event.data)
 | 
				
			||||||
                if (type === 'get_music_list') {
 | 
					                if (data.type === 'get_user_profile') {
 | 
				
			||||||
 | 
					                    console.log(client.name, '请求身份信息:', data)
 | 
				
			||||||
 | 
					                    //clientList.sendto(client.id, 'base', JSON.stringify({
 | 
				
			||||||
 | 
					                    //    type: 'set_user_profile',
 | 
				
			||||||
 | 
					                    //    name: name,
 | 
				
			||||||
 | 
					                    //    avatar: avatar,
 | 
				
			||||||
 | 
					                    //}))
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (data.type === 'set_user_profile') {
 | 
				
			||||||
 | 
					                    console.log(client.name, '发来身份信息:', data)
 | 
				
			||||||
 | 
					                    console.log('将身份信息保存到本机记录:', client)
 | 
				
			||||||
 | 
					                    client.name = data.name
 | 
				
			||||||
 | 
					                    client.avatar = data.avatar
 | 
				
			||||||
 | 
					                    // 还需要更新组件的用户信息
 | 
				
			||||||
 | 
					                    console.log('更新组件的用户信息:', data, client)
 | 
				
			||||||
 | 
					                    clientList.setAvatar({ id:client.id, ...data })
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (data.type === 'get_music_list') {
 | 
				
			||||||
                    const ms = musicList.list.filter(item => item.arrayBuffer)
 | 
					                    const ms = musicList.list.filter(item => item.arrayBuffer)
 | 
				
			||||||
                    console.log(client.name, '请求音乐列表:', ms)
 | 
					                    console.log(client.name, '请求音乐列表:', ms)
 | 
				
			||||||
                    clientList.sendto(client.id, 'base', JSON.stringify({
 | 
					                    clientList.sendto(client.id, 'base', JSON.stringify({
 | 
				
			||||||
@@ -162,20 +184,20 @@
 | 
				
			|||||||
                    }))
 | 
					                    }))
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (type === 'set_music_list') {
 | 
					                if (data.type === 'set_music_list') {
 | 
				
			||||||
                    console.log(client.name, '发来音乐列表:', `x${JSON.parse(event.data).list.length}`)
 | 
					                    console.log(client.name, '发来音乐列表:', `x${JSON.parse(event.data).list.length}`)
 | 
				
			||||||
                    console.log('将列表保存到本机记录:', client)
 | 
					                    console.log('将列表保存到本机记录:', client)
 | 
				
			||||||
                    client.musicList = list
 | 
					                    client.musicList = data.list
 | 
				
			||||||
                    client.musicList.forEach(music => musicList.add(music))
 | 
					                    client.musicList.forEach(music => musicList.add(music))
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (type === 'get_music_data') {
 | 
					                if (data.type === 'get_music_data') {
 | 
				
			||||||
                    // 建立一个信道, 用于传输音乐数据(接收方已经准备好摘要信息)
 | 
					                    // 建立一个信道, 用于传输音乐数据(接收方已经准备好摘要信息)
 | 
				
			||||||
                    console.log(client.name, '建立一个信道, 用于传输音乐数据', musicList.list)
 | 
					                    console.log(client.name, '建立一个信道, 用于传输音乐数据', musicList.list)
 | 
				
			||||||
                    musicList.list.filter(item => item.id === id).forEach(item => {
 | 
					                    musicList.list.filter(item => item.id === data.id).forEach(item => {
 | 
				
			||||||
                        const ch = client.webrtc.createDataChannel(channel, { reliable: true })
 | 
					                        const ch = client.webrtc.createDataChannel(data.channel, { reliable: true })
 | 
				
			||||||
                        ch.onopen = async event => {
 | 
					                        ch.onopen = async event => {
 | 
				
			||||||
                            console.log(client.name, `打开 ${channel} 信道传输音乐数据`, item.name)
 | 
					                            console.log(client.name, `打开 ${data.channel} 信道传输音乐数据`, item.name)
 | 
				
			||||||
                            // 将音乐数据分成多个小块,并逐个发送
 | 
					                            // 将音乐数据分成多个小块,并逐个发送
 | 
				
			||||||
                            async function sendChunk(dataChannel, data, index = 0, buffer = new ArrayBuffer(0)) {
 | 
					                            async function sendChunk(dataChannel, data, index = 0, buffer = new ArrayBuffer(0)) {
 | 
				
			||||||
                                while (index < data.byteLength) {
 | 
					                                while (index < data.byteLength) {
 | 
				
			||||||
@@ -190,13 +212,13 @@
 | 
				
			|||||||
                                return buffer
 | 
					                                return buffer
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            await sendChunk(ch, item.arrayBuffer)
 | 
					                            await sendChunk(ch, item.arrayBuffer)
 | 
				
			||||||
                            console.log(client.name, `获取 ${channel} 信道数据结束`, item.name)
 | 
					                            console.log(client.name, `获取 ${data.channel} 信道数据结束`, item.name)
 | 
				
			||||||
                            ch.close() // 关闭信道
 | 
					                            ch.close() // 关闭信道
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                console.log('未知类型:', type)
 | 
					                console.log('未知类型:', data.type)
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            onclose: event => {
 | 
					            onclose: event => {
 | 
				
			||||||
                console.log('关闭信道', event.target.label)
 | 
					                console.log('关闭信道', event.target.label)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user