code: func (t *TerminalHandler) streamEvents(ws *websocket.Conn, tc *client.TeleportClient) {
  	for {
  		select {
  		// Send push events that come over the events channel to the web client.
  		case event := <-tc.EventsChannel():
  			data, err := json.Marshal(event)
  			if err != nil {
  				t.log.Errorf("Unable to marshal audit event %v: %v.", event.GetType(), err)
  				continue
  			}
  
  			t.log.Debugf("Sending audit event %v to web client.", event.GetType())
  
  			// UTF-8 encode the error message and then wrap it in a raw envelope.
  			encodedPayload, err := t.encoder.String(string(data))
  			if err != nil {
  				t.log.Debugf("Unable to send audit event %v to web client: %v.", event.GetType(), err)
  				continue
  			}
  			envelope := &Envelope{
  				Version: defaults.WebsocketVersion,
  				Type:    defaults.WebsocketAudit,
  				Payload: encodedPayload,
  			}
  			envelopeBytes, err := proto.Marshal(envelope)
  			if err != nil {
  				t.log.Debugf("Unable to send audit event %v to web client: %v.", event.GetType(), err)
  				continue
  			}
  
  			// Send bytes over the websocket to the web client.
  			err = websocket.Message.Send(ws, envelopeBytes)
  			if err != nil {
  				t.log.Errorf("Unable to send audit event %v to web client: %v.", event.GetType(), err)
  				continue
  			}
  		// Once the terminal stream is over (and the close envelope has been sent),
  		// close stop streaming envelopes.
  		case <-t.terminalContext.Done():
  			return
  		}
  	}
  }
docs: // streamEvents receives events over the SSH connection and forwards them to
  // the web client.