일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- REST API
- Three-fiber
- webrtc
- babel
- Babel standalone
- Image Resize typescript
- Raycasting
- androidId
- uint16array
- Prism.js
- uint8array
- identifierForVender
- Game js
- typescript
- methodChannel
- Completer
- react
- Redux
- FirebaseAnalytics
- web track
- jszip
- Three js
- code editor
- KakaoMap
- Excel
- userevent_tracker
- node
- RouteObserver
- swagger-typescript-api
- Flutter
- Today
- Total
Never give up
WebRTC - 2. Signaling server with node express 본문
이전 포스트에서 peer와 peer를 연결할 때
signaling server를 이용한다고 했는데
필자는 socket으로 구현을 해봤습니다
const ip = require('ip')
const express = require('express');
const app = express();
const server = app.listen(9000, ip.address(), () => {
const address = server.address()
console.log(`[scoket] on ${address.address}:${address.port}`)
});
const io = require('socket.io')(server, {
cors: {
origin: "*",
}
})
let userList = []
io.on('connection', (socket) => {
const userId = socket.id
userList = [...userList, userId]
console.log('[connection] userLogin', { userId })
// 유저 연결시 데이터 보냄
// broadcast로 보낼경우 접속시 다른 유저 접속상태를 알 수 없음
io.emit('updateUserlist', { userList })
console.log('[connection] userList sent', { userList })
// offer가 왔을 때 처리
// 1. [caller] 본인 아이디, 상대 아이디, offer data 전달
// 2. 상대에게 본인 아이디, offer data 전달
socket.on('offer', (data) => {
let { to, from, offerType, offerSDP, audioOnly } = data
console.log('[offer] data', { to, from, audioOnly })
socket.to(to).emit('offer', { from, offerSDP, offerType, audioOnly })
})
// offer refuse 처리
socket.on('refuse', (data) => {
const { to } = data
console.log('[offer] refuse', { to })
socket.to(to).emit('refuse')
})
// offer 요청에 대한 answer 응답 처리
// 1. [callee] 상대방 아이디, answer data 전달
// 2. 상대에게 answer data 전달
socket.on('answer', (data) => {
const { to, answerSDP, answerType } = data
console.log('[answer] data', { to })
socket.to(to).emit('answer', { answerSDP, answerType })
})
// ice candidate
// send offer/answer 발생시 상대방에게 network정보 전달
socket.on('iceCandidate', (data) => {
const { to, candidate, sdpMid, sdpMLineIndex } = data
console.log('[iceCandidate] data', { to, candidate, sdpMid, sdpMLineIndex })
socket.to(to).emit('remoteIceCandidate', { candidate, sdpMid, sdpMLineIndex, to })
})
// close peer connection
socket.on('disconnectPeer', (data) => {
const { to } = data
console.log('[disconnect] to ', { to })
if (to !== null) {
socket.to(to).emit('disconnectPeer')
}
})
// 연결 해제시 userlist update
socket.on('disconnect', () => {
userList = userList.filter((user) => user !== userId)
socket.broadcast.emit('updateUserlist', { userList })
console.log('[disconnected] id : ', userId)
})
})
먼저 앱의 경우 localhost로 테스트가 불가능해서 ip 라이브러리를 이용해서
간단하게 ip부분을 셋팅해주고 소켓을 만들어줍니다
필자가 사용한 이벤트를 보면
1. updateUserList : 유저가 들어올때마다 유저리스트를 갱신해줍니다
2. offer : caller가 callee에게 offer를 합니다
3.1 refuse : caller의 offer를 거절합니다
3.2 answer : caller의 offer에 대한 응답을 해줍니다
4. iceCandidate : ice candidate 정보를 서로에게 교환해줍니다
5. disconnectPeer : 연결 중 연결을 해제할 때 사용합니다
6. disconnect : 유저가 앱 혹은 웹을 종료할 때 사용합니다
추가로 필자는 userId를 별도로 생성해주지 않고
socketID로 연결했는데, 유저 고유의 아이디로 만들어서
관리하면 조금 더 개선된(?) 형태가 되지않을까 합니다
일단 서버부분은 테스트용으로 간단하게(?) 셋팅해봤고
다음 포스트로 app과 web에서 실제로 어떻게 작동하는지 보면 되겠습니다
Intro : https://devmemory.tistory.com/103
React : https://devmemory.tistory.com/105
Flutter : https://devmemory.tistory.com/106
Outro : https://devmemory.tistory.com/107
'WebRTC' 카테고리의 다른 글
WebRTC - 5. Outro (gif, github link) (4) | 2022.10.08 |
---|---|
WebRTC - 4. Flutter WebRTC (2) | 2022.10.08 |
WebRTC - 3. React WebRTC (0) | 2022.10.08 |
WebRTC - 1. intro (1) | 2022.10.08 |