Advertisement
Guest User

Untitled

a guest
Feb 26th, 2020
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. import { channel, Sender, Receiver }       from '../channel/index'
  3.  
  4. import { Barrier }                         from '../async/index'
  5.  
  6. import { Hub, Address, Forward, Protocol } from './hub'
  7.  
  8. export class NetworkHub implements Hub {
  9.  
  10.     private readonly sender:   Sender<[Address, any]>
  11.    
  12.     private readonly receiver: Receiver<[Address, any]>
  13.    
  14.     private readonly barrier:  Barrier
  15.    
  16.     private readonly socket:   WebSocket
  17.    
  18.     private configuration?:    RTCConfiguration
  19.    
  20.     private address?:          Address
  21.  
  22.     constructor(private readonly endpoint: string) {
  23.  
  24.         const [sender, receiver] = channel<[Address, any]>()
  25.        
  26.         this.sender   = sender
  27.        
  28.         this.receiver = receiver
  29.        
  30.         this.barrier  = new Barrier()
  31.        
  32.         this.socket   = new WebSocket(this.endpoint)
  33.        
  34.         this.socket.addEventListener('message', event => this.on_message(event))
  35.        
  36.         this.socket.addEventListener('error',   event => this.on_error(event))
  37.        
  38.         this.socket.addEventListener('close',   ()    => this.on_close())
  39.     }
  40.  
  41.     /** Returns this hubs network binding information */
  42.     public binding(): Promise<[Address, RTCConfiguration]> {
  43.  
  44.         return this.barrier.run(() => [this.address!, this.configuration!])
  45.     }
  46.  
  47.     /** Sends a message to a peer on the network. */
  48.     public send<T>(to: Address, data: T): Promise<void> {
  49.  
  50.         return this.barrier.run(() => {
  51.  
  52.             const type    = 'forward'
  53.  
  54.             const from    = this.address!
  55.  
  56.             const forward = { type, from, to, data } as Forward
  57.  
  58.             this.socket.send(JSON.stringify(forward) )
  59.         })
  60.     }
  61.  
  62.     /** Receives a message from a peer on the network. */
  63.     public async receive(): Promise<[Address, any]> {
  64.        
  65.         const { value } = await this.receiver.next()
  66.        
  67.         return value as [Address, any]
  68.     }
  69.  
  70.     private on_message(event: MessageEvent) {
  71.  
  72.         const protocol = JSON.parse(event.data) as Protocol
  73.  
  74.         switch(protocol.type) {
  75.  
  76.             case 'binding': {
  77.  
  78.                 const { address, configuration } = protocol
  79.  
  80.                 this.configuration = configuration
  81.  
  82.                 this.address       = address
  83.  
  84.                 this.barrier.resume()
  85.  
  86.                 break
  87.             }
  88.             case 'forward': {
  89.  
  90.                 const { from, data } = protocol
  91.  
  92.                 this.sender.send([from, data])
  93.  
  94.                 break
  95.             }
  96.         }
  97.     }
  98.  
  99.     private on_error(error: Event) {
  100.  
  101.         this.sender.end()
  102.  
  103.         throw error
  104.     }
  105.  
  106.     private on_close() {
  107.  
  108.         this.sender.end()
  109.     }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement