Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Latest commit

 

History

History
272 lines (219 loc) · 12.2 KB

File metadata and controls

272 lines (219 loc) · 12.2 KB

BlackBerry Spark Communications Services

Data Transfer for JavaScript

The Data Transfer example application demonstrates how to use the peer-to-peer data connection feature of BlackBerry Spark Communications Services. The data connection API allows arbitrary data to be sent securely through a familiar stream interface.

This example builds on the Quick Start example that demonstrates setting up the SDK in a domain with user authentication disabled and the BlackBerry Key Management Service enabled.

Features

The Data Transfer example allows the user to do the following:

  • Start a data connection
  • Send and receive files over the connection

Getting Started

This example requires the Spark Communications SDK, which you can find along with related resources at the locations below.

YouTube Getting Started Video

Getting started video

This example application works in a sandbox domain with user authentication disabled and the BlackBerry Key Management Service enabled. See the Download & Configure section of the Developer Guide to get started configuring a domain in the sandbox.

When you have a domain in the sandbox, edit Data Transfer's config_mock.js file to configure the example with your domain ID and a key passcode.

Set the SDK_CONFIG.domain parameter to your sandbox domain ID.

const SDK_CONFIG = {
  domain: 'your_domain_id'
};

Set the KEY_PASSCODE parameter to the string used to protect the logged in user's keys stored in the BlackBerry Key Management Service. Real applications should not use the same passcode for all users. However, it allows this example application to be smaller and focus on demonstrating its call functionality instead of passcode management.

const KEY_PASSCODE = 'passcode';

Run yarn install in the Data Transfer application directory to install the required packages.

When you run the Data Transfer application, it will prompt you for a user ID. Because you've configured your domain to have user authentication disabled, you can enter any string you like for the user ID and an SDK identity will be created for it. Other applications that you run in the same domain will be able to find this identity by this user ID.

Walkthrough

Before a chat with a configured user can be initiated, the user must be authenticated and the SDK started.

Follow this guide for a walkthrough of how to share data over a secure peer-to-peer data connection. This walkthrough describes the functionality provided by the data-transfer-element component, which can be found in js/dataTransferElement.js.

Creating a connection

The onConnectClicked() event handler starts a new data connection using SparkCommunications.Media.createDataConnection(). When starting a data connection, the metadata object will be sent to the callee to describe the intent or content of the connection.

  // Create connection to the specified regId.
  this.bbmSdk.media.createDataConnection(
    new SparkCommunications.Media.Callee(this.contactRegId), metaData)
  .then(connection => {
    connection.on('connected', () => {
      this.connection = connection;
      this.connectionState = STATE_CONNECTED;
    });
  });

Receive a connection

When the setBbmSdk() function is called, the component will use the SDK instance to monitor for incoming data connections by subscribing to the incomingDataConnection event. This event is triggered each time a new incoming data connection request arrives. The event given to the event handler provides the application with the incoming DataConnection instance which can be accepted or declined.

  this.bbmSdk.media.on('incomingDataConnection', connection => {
    const contactRegId = connection.callParty.regId;
    const messageString = `${contactRegId} wants to establish a connection.  Do you want to accept?`
      if (confirm(messageString)) {
      connection.accept()
      .then(() => {
        this.connection = connection;
        this.connectionState = STATE_CONNECTED;
        this.contactRegId = contactRegId;
      })
      .catch(error => {
        alert('Failed to accept connection');
        console.error(`Failed to accept connection: ${error}`);
      });
    }
    else {
      connection.end(SparkCommunications.Media.CallEndReason.REJECT_CALL);
    }
  });

Receiving a file

To receive data using the established DataConnection, the application must subscribe to the dataReceived event. The event handler for this event will receive the DataReceiver instance that will handle all incoming data over the DataConnection.

To receive a notification that the DataConnection has been closed, subscribe to the disconnected event. The event handler will receive the DataConnection that was closed and a status that indicates why the connection was closed.

The context for this snippet can be found in the onConnectionChanged() callback.

  // Subscribe to the new connection events.
  newConnection.on('dataReceived', onDataReceived);
  newConnection.on('disconnected', onDisconnected);

To specify the receiving mode, the DataReceiver must be configured within the dataReceived event handler. The Data Transfer application only operates on the complete data, so the DATA_FULL mode is used.

The context for this snippet can be found in the onReceiverChanged() callback.

  newReceiver.configure({
    mode: SparkCommunications.Media.DataConnection.DataReceiver.Mode.DATA_FULL
  });

To receive notification that all of the incoming data has been received, subscribe to the done event.

The context for this snippet can be found in the onReceiverChanged() callback.

  // Subscribe to 'done' event of the newReceiver
  newReceiver.on('done', onDone);

The deplete method is used to consume the data that has been buffered within the DataReceiver. The Data Transfer example creates a blob from the received data, which is used by the UI to show the received data.

The context for this snippet can be found in the onReceiverChanged() callback.

  const onDone = receiver => {
    // File is received.
    const data = receiver.deplete();
    const blob = new Blob([data], {
      type: receiver.header.type
    });
    const url = window.URL.createObjectURL(blob);
    // Set percentage to 100%. Set file name and download URL.
    this.set(`fileTransfers.0.percentage`, `100%`);
    this.set(`fileTransfers.0.fileUrl`, url);
    this.set(`fileTransfers.0.fileName`, receiver.header.name);
  };

Sending a file

To send a file, call the sendFile method on an established DataConnection instance. The Data Transfer example shows the progress of the file transfer by providing a progress callback.

The context for this snippet can be found in the onInputFileChange() callback.

  // Send user selected file.
  this.connection.sendFile(file, percentage => {
    this.set(`fileTransfers.0.percentage`, `${percentage}%`);
  })
  .then(() => {
    // File is sent. Set percentage to 100%.
    this.set(`fileTransfers.0.percentage`, `100%`);
    this.set(`fileTransfers.0.isSent`, true);
  }).catch(error => {
    alert(error);
  });

License

These examples are released as Open Source and licensed under the Apache 2.0 License.

This page includes icons from: https://material.io/icons/ used under the Apache 2.0 License.

Reporting Issues and Feature Requests

If you find a issue in one of the Samples or have a Feature Request, simply file an issue.