Home Reference Source

js/Channel.js

  1. import Mitt from './util/Mitt.js'
  2.  
  3. /**
  4. * 양방향 데이터 전송을 위한 인터페이스. RTCSocket을 이용해 데이터를 전송합니다.
  5. */
  6. export default class Channel extends Mitt {
  7. /**
  8. * 주의: 이 생성자는 RTCEngine 내부에서만 호출되어야 합니다.
  9. * @param {RTCSocket} socket 데이터 전송에 사용할 RTCSocket
  10. * @param {RTCEngine} engine 이 채널을 생성한 엔진
  11. */
  12. constructor (socket, engine) {
  13. super()
  14.  
  15. this.engine = engine
  16. this.socket = socket
  17. this.socket.on('data', data => this.emit('message', data))
  18. this.label = this.socket.dataChannel.label
  19. this.filesSent = 0
  20.  
  21. this.socket.on('__file-transaction', label => this.receiveTransaction(label))
  22. }
  23.  
  24. /**
  25. * 상대가 파일을 보내기 위해 트렌젝션을 만들었을때 파일을 받기 위한 트렌젝션을 생성하고 `transaction` 이벤트로 알립니다.
  26. * @deprecated
  27. * @param {string} label 트렌젝션의 식별자
  28. */
  29. async receiveTransaction (label) {
  30. const transaction = await this.engine.readable(label)
  31. this.emit('transaction', transaction)
  32. }
  33.  
  34. /**
  35. * 채널을 통해서 데이터를 전송합니다. `File` 데이터를 받으면 새로운 트렌젝션을 만들고 그걸 통해 파일의 데이터를 전송합니다.
  36. * 받는쪽에서는 `transaction` 이벤트를 통해 파일을 받을 수 있습니다.
  37. * @deprecated
  38. * @param {*} data 전송할 데이터. `JSON.stringify()`로 JSON 문자열로 바꿀 수 있거나 `ArrayBuffer`의 타입은 그냥 전송하고, `File`인 경우 새로운 트렌젝션을 만듭니다.
  39. * @returns {Promise<Transaction|void>} 파일 전송을 위한 트렌젝션 또는 데이터가 성공적으로 전송되면 resolve하는 promise
  40. */
  41. async send (data) {
  42. if (data instanceof File) {
  43. const file = data
  44. const label = `file - ${this.filesSent++}`
  45. this.socket.writeEvent('__file-transaction', label)
  46.  
  47. const transaction = await this.engine.writable(label, {
  48. name: file.name,
  49. size: file.size
  50. })
  51.  
  52. file.stream().pipeTo(transaction.stream)
  53. return transaction
  54. }
  55.  
  56. return this.socket.write(data)
  57. }
  58. }