Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

rpcOld.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. const connections = {}
  2. const datachannels = {}
  3. const videoElements = {}
  4. function setStream({source, stream}) {
  5. const element = videoElements[source]
  6. const active = element && element.srcObject
  7. if(active && active.id !== stream.id) {
  8. videoElements[source].srcObject.getTracks().forEach(tr => tr.stop())
  9. }
  10. element.srcObject = stream
  11. if(source === State.username) {
  12. signal({kind: 'stream-refresh'})
  13. }
  14. }
  15. function reloadAllStreams() {
  16. State.online.forEach(username => {
  17. const rpc = connections[username]
  18. if(rpc) {
  19. rpc.getSenders().map(s => console.log(s) || rpc.removeTrack(s))
  20. }
  21. signal({kind: 'rpc', value: {type: 'request'}, source: username})
  22. })
  23. }
  24. function createConnection(target) {
  25. const rpc = new RTCPeerConnection(rpcConfig)
  26. rpc.onicecandidate = ({candidate}) => {
  27. if(candidate && candidate.candidate) {
  28. const value = {type: 'candidate', candidate}
  29. wire({kind: 'rpc', value, target})
  30. }
  31. }
  32. rpc.ontrack = ({streams: [stream]}) => {
  33. setStream({source: target, stream})
  34. }
  35. rpc.onconnectionstatechange = () => {
  36. if(rpc.connectionState === 'failed') {
  37. console.log(target, 'failed, retry!')
  38. wire({kind: 'rpc', value: {type: 'request'}, target})
  39. }
  40. }
  41. rpc.ondatachannel = ({channel}) => {
  42. datachannels[target] = channel
  43. datachannels[target].onmessage = ({data}) => console.log(data)
  44. // for testing purposes
  45. const msg = `rpc established from ${target} to ${State.username}`
  46. datachannels[target].send(msg)
  47. console.log(msg)
  48. }
  49. rpc.onnegotiationneeded = () => {
  50. console.log('lmao renegotiate bi')
  51. }
  52. connections[target] = rpc
  53. if(State.username > target) {
  54. datachannels[target] = rpc.createDataChannel('test')
  55. datachannels[target].onmessage = ({data}) => console.log(data)
  56. signal({kind: 'rpc', value: {type: 'request'}, source: target})
  57. }
  58. }
  59. function setSenders(rpc, username) {
  60. const element = videoElements[username]
  61. const stream = element && element.srcObject
  62. rpc.getSenders().forEach(se => rpc.removeTrack(se))
  63. if(stream) {
  64. stream.getTracks().forEach(tr => rpc.addTrack(tr, stream))
  65. }
  66. }
  67. async function handlePeerInfo({source: target, value, kind}) {
  68. const rpc = connections[target]
  69. if(!rpc) {
  70. return
  71. }
  72. if(value.type === 'request') {
  73. const localOffer = await rpc.createOffer()
  74. await rpc.setLocalDescription(localOffer)
  75. wire({kind, value: localOffer, target})
  76. }
  77. else if(value.type === 'offer') {
  78. const remoteOffer = new RTCSessionDescription(value)
  79. await rpc.setRemoteDescription(remoteOffer)
  80. const localAnswer = await rpc.createAnswer()
  81. await rpc.setLocalDescription(localAnswer)
  82. wire({kind, value: localAnswer, target})
  83. }
  84. else if(value.type === 'answer') {
  85. const remoteAnswer = new RTCSessionDescription(value)
  86. await rpc.setRemoteDescription(remoteAnswer).catch(e => e)
  87. }
  88. else if(value.type === 'candidate') {
  89. const candidate = new RTCIceCandidate(value.candidate)
  90. await rpc.addIceCandidate(candidate).catch(e => e)
  91. }
  92. }
  93. function destroyConnection(username) {
  94. if(datachannels[username]) {
  95. datachannels[username].close()
  96. delete datachannels[username]
  97. }
  98. if(connections[username]) {
  99. connections[username].getReceivers().forEach(r => r.track.stop())
  100. connections[username].close()
  101. delete connections[username]
  102. }
  103. }
  104. function destroyAll() {
  105. const people = new Set()
  106. const collect = [connections, datachannels, streams, screen]
  107. .map(collection => Object.keys(collection))
  108. .forEach(keys => keys.forEach(key => people.add(key)))
  109. people.forEach(destroyConnection)
  110. }
  111. addEventListener('stream-refresh', reloadAllStreams)
  112. addEventListener('stream', (e) => setStream(e.detail.value))
  113. addEventListener('rpc', (e) => handlePeerInfo(e.detail))
  114. addEventListener('join', (e) => createConnection(e.detail.value))
  115. addEventListener('leave', (e) => destroyConnection(e.detail.value))
  116. addEventListener('logout', () => destroyAll())
  117. addEventListener('load', () => doNotLog.add('rpc'))