<commit_before>import server from '../core/server';
import Service from '../core/Service';
import serviceManager from '../core/serviceManager';
import { Server as WebSocketServer } from 'ws';
import http from 'http';
import https from 'https';
import pem from 'pem';
import fs from 'fs';
import colors from 'colors';

const SERVICE_ID = 'service:raw-socket';


/**
 * Protocol defined in configuration is added to these two entry that manage
 * the handshake at the creation of the socket.
 * @private
 */
const baseProtocol = [
  { channel: 'service:handshake', type: 'Uint32' },
  { channel: 'service:handshake-ack', type: 'Uint8' },
];

/**
 * Counter that create tokens in order to match sockets and clients.
 * @private
 */
let counter = 0;

/**
 * Interface for the `raw-socket` service.
 *
 * This service creates an additionnal native socket with its binary type set
 * to `arraybuffer` and focused on performances.
 * It allows the transfert of `TypedArray` data wrapped with a minimal channel
 * mechanism (up to 256 channels).
 *
 * The user-defined protocol must follow the convention:
 * @example
 * const protocol = [
 *   { channel: 'my-channel', type: 'Float32' }
 *   // ...
 * ]
 *
 * Where the `channel` can be any string and the `type` can be interpolated
 * to any `TypedArray` by concatenating `'Array'` at its end.
 *
 * __*The service must be used with its [client-side counterpart]{@link module:soundworks/client.RawSocket}*__
 *
 * @memberof module:soundworks/server
 */
class RawSocket extends Service {
  constructor() {
    super(SERVICE_ID);

    console.error('[deprecated] RawSocket service is deprecated and will be removed in soundworks#v3.0.0. Please update your application to use `client.socket.[sendBinary|receiveBinary]` instead');

    const defaults = {
      configItem: 'rawSocket',
    };

    this.configure(defaults);

    this._port = null;
    this._protocol = null;
    this._channels = null;

    /**
     * Listeners for the incomming messages.
     *
     * @type {Map<client, Set<Function>>}
     * @name _listeners
     * @memberof module:soundworks/server.RawSocket
     * @instance
     * @private
     */
    this._listeners = new Map();

    this._tokenClientMap = new Map();
    this._clientSocketMap = new Map();
    this._socketClientMap = new Map();

    this._protocol = baseProtocol;

    // retrieve service config + useHttps
    this._sharedConfig = this.require('shared-config');

    this._onConnection = this._onConnection.bind(this);
  }

  configure(options) {
    if (options.protocol) {
      this._protocol = this._protocol.concat(options.protocol);
    }

    super.configure(options);
  }

  addProtocolDefinition(def) {
    this._protocol.push(def);
  }

  /** @private */
  start() {
    super.start();

    const configItem = this.options.configItem;
    const config = this._sharedConfig.get(configItem);

    this._port = config.port;

    if (Array.isArray(config.protocol))
      this._protocol = this.protocol.concat(config.protocol);

    this._channels = this._protocol.map((def) => def.channel);

    // check http / https mode
    let useHttps = server.config.useHttps;

    // launch http(s) server
    if (!useHttps) {
      let httpServer = http.createServer();
      this.runServer(httpServer);
    } else {
      const httpsInfos = server.config.httpsInfos;

      // use given certificate
      if (httpsInfos.key && httpsInfos.cert) {
        const key = fs.readFileSync(httpsInfos.key);
        const cert = fs.readFileSync(httpsInfos.cert);

        let httpsServer = https.createServer({ key: key, cert: cert });
        this.runServer(httpsServer);
      // generate certificate on the fly (for development purposes)
      } else {
        pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
          let httpsServer = https.createServer({ key: keys.serviceKey, cert: keys.certificate });
          this.runServer(httpsServer);
        });
      }
    }
  }

  runServer(server){
    server.listen(this._port, () => {
      console.log(colors.yellow('+ binary WebSocket server listening on port:', this._port));
    });

    this._wss = new WebSocketServer({ server: server });
    this._wss.on('connection', this._onConnection);
    this.ready();
  }

  /** @private */<commit_msg>moved from colors to chalk<commit_after>import http from 'http';
import https from 'https';
import pem from 'pem';
import fs from 'fs';
import chalk from 'chalk';
import { Server as WebSocketServer } from 'ws';
import server from '../core/server';
import Service from '../core/Service';
import serviceManager from '../core/serviceManager';

const SERVICE_ID = 'service:raw-socket';


/**
 * Protocol defined in configuration is added to these two entry that manage
 * the handshake at the creation of the socket.
 * @private
 */
const baseProtocol = [
  { channel: 'service:handshake', type: 'Uint32' },
  { channel: 'service:handshake-ack', type: 'Uint8' },
];

/**
 * Counter that create tokens in order to match sockets and clients.
 * @private
 */
let counter = 0;

/**
 * Interface for the `raw-socket` service.
 *
 * This service creates an additionnal native socket with its binary type set
 * to `arraybuffer` and focused on performances.
 * It allows the transfert of `TypedArray` data wrapped with a minimal channel
 * mechanism (up to 256 channels).
 *
 * The user-defined protocol must follow the convention:
 * @example
 * const protocol = [
 *   { channel: 'my-channel', type: 'Float32' }
 *   // ...
 * ]
 *
 * Where the `channel` can be any string and the `type` can be interpolated
 * to any `TypedArray` by concatenating `'Array'` at its end.
 *
 * __*The service must be used with its [client-side counterpart]{@link module:soundworks/client.RawSocket}*__
 *
 * @memberof module:soundworks/server
 */
class RawSocket extends Service {
  constructor() {
    super(SERVICE_ID);

    console.error('[deprecated] RawSocket service is deprecated and will be removed in soundworks#v3.0.0. Please update your application to use `client.socket.[sendBinary|receiveBinary]` instead');

    const defaults = {
      configItem: 'rawSocket',
    };

    this.configure(defaults);

    this._port = null;
    this._protocol = null;
    this._channels = null;

    /**
     * Listeners for the incomming messages.
     *
     * @type {Map<client, Set<Function>>}
     * @name _listeners
     * @memberof module:soundworks/server.RawSocket
     * @instance
     * @private
     */
    this._listeners = new Map();

    this._tokenClientMap = new Map();
    this._clientSocketMap = new Map();
    this._socketClientMap = new Map();

    this._protocol = baseProtocol;

    // retrieve service config + useHttps
    this._sharedConfig = this.require('shared-config');

    this._onConnection = this._onConnection.bind(this);
  }

  configure(options) {
    if (options.protocol) {
      this._protocol = this._protocol.concat(options.protocol);
    }

    super.configure(options);
  }

  addProtocolDefinition(def) {
    this._protocol.push(def);
  }

  /** @private */
  start() {
    super.start();

    const configItem = this.options.configItem;
    const config = this._sharedConfig.get(configItem);

    this._port = config.port;

    if (Array.isArray(config.protocol))
      this._protocol = this.protocol.concat(config.protocol);

    this._channels = this._protocol.map((def) => def.channel);

    // check http / https mode
    let useHttps = server.config.useHttps;

    // launch http(s) server
    if (!useHttps) {
      let httpServer = http.createServer();
      this.runServer(httpServer);
    } else {
      const httpsInfos = server.config.httpsInfos;

      // use given certificate
      if (httpsInfos.key && httpsInfos.cert) {
        const key = fs.readFileSync(httpsInfos.key);
        const cert = fs.readFileSync(httpsInfos.cert);

        let httpsServer = https.createServer({ key: key, cert: cert });
        this.runServer(httpsServer);
      // generate certificate on the fly (for development purposes)
      } else {
        pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
          let httpsServer = https.createServer({ key: keys.serviceKey, cert: keys.certificate });
          this.runServer(httpsServer);
        });
      }
    }
  }

  runServer(server){
    server.listen(this._port, () => {
      console.log(chalk.yellow('+ binary WebSocket server listening on port:', this._port));
    });

    this._wss = new WebSocketServer({ server: server });
    this._wss.on('connection', this._onConnection);
    this.ready();
  }

  /** @private */
{'fraction_non_alphanumeric': 0.12659698025551683, 'fraction_numerical': 0.0030197444831591173, 'mean_word_length': 3.1379144641999037, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3376360', 'n_tokens_mistral': 2556, 'n_tokens_neox': 2481, 'n_words': 716}