Home Reference Source

src/SignalingConnection.js

import Context from './Context';
import l from './Logger';

function SignalingConnection({ url, context }) {
  const connection = (function createConnection() {
    l.g('Signaling: Connect');
    const webSocket = new WebSocket(url);
    l.d('Signaling Connection: ', webSocket);
    l.gEnd();
    return webSocket;
  }());

  function send(...args) {
    return connection.send(...args);
  }
  function close(){
    if (connection.readyState<2){
      const message = createMessage({ command: 'disconnect' });
      l.v('disconnect Message ->:', message);
      send(JSON.stringify(message));
      connection.close();
    }
  }

  function onMessage(handler) {
    connection.onmessage = handler;
  }

  function handleOpenEvent(event) {
    l.i('Signaling: Success connect to the signaling server');
    l.v('OpenEvent:', event);
    if (context.eventManager.hasEventListener('onInit')){
      context.eventManager.dispatchEvent('onInit', context.token);
    }
    if (context.eventManager.hasEventListener('onStateChange')) {
      context.eventManager.dispatchEvent('onStateChange', 'INIT');
    }
  }

  function handleCloseEvent(event) {
    l.i('Signaling: Closed the signaling connection');
    l.v('Event:', event);
  }

  function handleErrorEvent(event) {
    l.i('Signaling: Error from the signaling connection.');
    l.v('Event', event);
    if (context.eventManager.hasEventListener('onError')) { context.eventManager.dispatchEvent('onError', 'WebSocketFailedError'); }
  }

  function createMessage({ command, body }) {
    l.i('Signaling: Create Message');

    const template = {
      command,
      token: context.token,
      serviceId: context.serviceId,
      channel: {
        id: context.channel.id,
      },
    };

    if (body) {
      template.body = body;
    }
    l.v("createMessage: "+ JSON.stringify(template));
    return template;
  }

  function connectChannel(channelId) {
    l.i('Signaling: Connect channel: As a caller');
    context.startTime = new Date().getTime();
    context.isCaller = true;
    context.channel.id = channelId;

    const message = createMessage({ command: 'connect' });
    l.v('ConnectCh Message ->:', message);

    send(JSON.stringify(message));
  }
  function createViewerChannel(channelId){
    l.i('Signaling: Create channel: As a viewer');
    context.startTime = new Date().getTime();
    context.isCaller = false;
    context.channel.id = channelId;

    const message = createMessage({ command: 'create' });
    message.channel.type="VIEWER";
    l.v('ConnectCh Message ->:', message);

    send(JSON.stringify(message));
  }
  function createBroadcastChannel(channelId) {
    l.i('Signaling: Create channel: As a presenter');
    context.startTime = new Date().getTime();
    context.isCaller = false;
    context.channel.id = channelId;

    const message = createMessage({ command: 'create' });
    message.channel.type="BROADCAST";
    l.v('ConnectCh Message ->:', message);

    send(JSON.stringify(message));
  }

  connection.onopen = handleOpenEvent;
  connection.onclose = handleCloseEvent;
  connection.onerror = handleErrorEvent;

  return Object.freeze({
    connectChannel,
    createMessage,
    createViewerChannel,
    createBroadcastChannel,
    send,
    close,
    onMessage,
    context,
  });
}

export default SignalingConnection;