44 | );
45 | }
46 | }
47 |
48 | module.exports = Users;
49 |
--------------------------------------------------------------------------------
/website/docs/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: installation
3 | title: Getting Started
4 | sidebar_label: Installation
5 | ---
6 |
7 | *_PeerData_* is a library for bidirectional peer-to-peer transfers of arbitrary data using [RTCDataChannel](https://developer.mozilla.org/pl/docs/Web/API/RTCDataChannel). Simple *WebRTC* wrapper providing data channel abstraction.
8 |
9 | [WebRTC](https://webrtc.org/) needs a messaging service to set up and maintain a *WebRTC* call.
10 |
11 | The sender and receiver *RTCPeerConnections* run in web pages on different devices, and we need a way for them to communicate metadata.
12 | For this, we use a signaling server: a server that can pass messages between *WebRTC* clients (peers).
13 |
14 | [PeerDataServer](https://github.com/vardius/peer-data-server) - An **ready to use** example of signaling server on *Node* using [socket.io](http://socket.io/).
15 |
16 | ## Installation
17 |
18 |
19 |
20 | ```yarn
21 | npm install peer-data
22 | ```
23 |
24 | ```bash
25 | yarn add peer-data
26 | ```
27 |
28 |
29 | [WebRTC Chat](https://github.com/vardius/webrtc-chat) server-less example application.
30 |
31 | [Shared versus Many `RCTPeerConnection`](https://bloggeek.me/webrtc-rtcpeerconnection-one-per-stream/)
32 |
33 | *_PeerData_* runs multiple `RCTPeerConnection` - one per user. Why? Main reason because it is easier to manage participants. With multiple `RTCPeerConnection` we’ve got a lot more flexibility, since the sessions are independent – each encapsulated in its own `RTCPeerConnection`.
34 |
--------------------------------------------------------------------------------
/examples/local-connection/remote.js:
--------------------------------------------------------------------------------
1 | window.remoteDispatcher.register("send", (event) => {
2 | console.log("remoteDispatcher:send", event);
3 | window.localDispatcher.dispatch(event.type, event);
4 | });
5 |
6 | // Set up servers
7 | const servers = {
8 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }],
9 | };
10 |
11 | const peerData = new window.PeerData(window.remoteDispatcher, servers);
12 | let room = null;
13 |
14 | async function connect(e) {
15 | if (room) {
16 | return;
17 | }
18 |
19 | // remote stream will receive our local stream and share it back for purpose of this example
20 | room = peerData.connect("test-room");
21 | room
22 | // you can catch errors here to know if the peer connection init failed
23 | .on("error", (event) => console.error("remote:error", event))
24 | .on("participant", (participant) => {
25 | // handle this participant error
26 | participant.on("error", (event) => console.error("participant:error", event));
27 |
28 | // this peer disconnected from room
29 | participant.on("disconnected", () => {
30 | console.log("remote:disconnected", event);
31 |
32 | // local peer has disconnected so we do the same, leave the room
33 | room.disconnect();
34 | room = null;
35 | });
36 |
37 | // this peer shared a stream
38 | participant.on("track", (event) => {
39 | console.log("remote:track", event);
40 | participant.addStream(event.streams[0]);
41 | });
42 | });
43 | }
44 |
45 | document.querySelector("#connect").addEventListener("click", (e) => connect(e));
--------------------------------------------------------------------------------
/website/docs/client.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: client
3 | title: Basic Example
4 | sidebar_label: Basic Example
5 | ---
6 |
7 | ## [WebRTC (Web Real-Time Communications)](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API)
8 |
9 | WebRTC is designed to work peer-to-peer, so users can connect by the most direct route possible. However, WebRTC is built to cope with real-world networking: client applications need to traverse NAT gateways and firewalls, and peer to peer networking needs fallbacks in case direct connection fails. As part of this process, the WebRTC APIs use STUN servers to get the IP address of your computer, and TURN servers to function as relay servers in case peer-to-peer communication fails. (WebRTC in the real world explains in more detail.)
10 |
11 | ## Example
12 |
13 | ```typescript
14 | import PeerData, { EventDispatcher, SocketChannel } from 'peer-data';
15 |
16 | const servers = {
17 | iceServers: [
18 | {urls: "stun:stun.1.google.com:19302"}
19 | ]
20 | };
21 |
22 | const dispatcher = new EventDispatcher();
23 | const peerData = new PeerData(dispatcher, servers);
24 | const signaling = new SocketChannel(dispatcher, 'http://localhost:8080');
25 |
26 | const room = peerData.connect('test-room');
27 |
28 | // returns participant object
29 | room.on("participant", participant => {
30 | //this peer disconnected from room
31 | participant.on("disconnected", () => console.log("disconnected"));
32 |
33 | //close connection, will dispatch disconnected event
34 | participant.close();
35 | });
36 |
37 | //exit room, will disconnect from all peers
38 | room.disconnect();
39 | ```
40 |
--------------------------------------------------------------------------------
/examples/data-channel/remote.js:
--------------------------------------------------------------------------------
1 | window.remoteDispatcher.register("send", (event) => {
2 | console.log("remoteDispatcher:send", event);
3 | window.localDispatcher.dispatch(event.type, event);
4 | });
5 |
6 | const constraints = {ordered: true};
7 | const servers = {
8 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }],
9 | };
10 |
11 | const peerData = new window.PeerData(window.remoteDispatcher, servers, constraints);
12 | let room = null;
13 |
14 | async function connect(e) {
15 | if (room) {
16 | return;
17 | }
18 |
19 | // remote stream will receive our local stream and share it back for purpose of this example
20 | room = peerData.connect("test-room");
21 | room
22 | // you can catch errors here to know if the peer connection init failed
23 | .on("error", (event) => console.error("remote:error", event))
24 | .on("participant", (participant) => {
25 | // handle this participant error
26 | participant.on("error", (event) => console.error("participant:error", event));
27 |
28 | participant.on("message", payload => {
29 | if (document.getElementById("remoteMessage").value !== "") {
30 | document.getElementById("remoteMessage").value += "\n"
31 | }
32 | document.getElementById("remoteMessage").value += payload
33 | });
34 |
35 | // this peer disconnected from room
36 | participant.on("disconnected", () => {
37 | console.log("remote:disconnected", event);
38 |
39 | // local peer has disconnected so we do the same, leave the room
40 | room.disconnect();
41 | room = null;
42 | });
43 | });
44 | }
45 |
46 | document.querySelector("#connect").addEventListener("click", (e) => connect(e));
--------------------------------------------------------------------------------
/examples/data-channel/local.js:
--------------------------------------------------------------------------------
1 | // Custom signaling system (we do not built in socket.io for local example)
2 | window.localDispatcher.register("send", (event) => {
3 | console.log("localDispatcher:send", event);
4 | window.remoteDispatcher.dispatch(event.type, event);
5 | });
6 |
7 | const constraints = {ordered: true};
8 | const servers = {
9 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }],
10 | };
11 |
12 | const peerData = new window.PeerData(window.localDispatcher, servers, constraints);
13 | let room = null;
14 | let remoteParticipant = null;
15 |
16 | async function connect(e) {
17 | if (room) {
18 | return;
19 | }
20 |
21 | // share our stream
22 | room = peerData.connect("test-room");
23 | room
24 | // you can catch errors here to know if the peer connection init failed
25 | .on("error", (event) => console.error("local:error", event))
26 | .on("participant", (participant) => {
27 | remoteParticipant = participant;
28 |
29 | // handle this participant error
30 | participant.on("error", (event) => console.error("participant:error", event));
31 | });
32 | }
33 |
34 | async function disconnect(e) {
35 | if (room) {
36 | room.disconnect();
37 | console.log('btn:disconnect');
38 | room = null;
39 | remoteParticipant = null;
40 | }
41 | }
42 |
43 | async function send(e) {
44 | if (remoteParticipant) {
45 | remoteParticipant.send(document.getElementById("localMessage").value);
46 | document.getElementById("localMessage").value = '';
47 | }
48 | }
49 |
50 | document.querySelector("#send").addEventListener("click", (e) => send(e));
51 | document.querySelector("#connect").addEventListener("click", (e) => connect(e));
52 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e));
53 |
--------------------------------------------------------------------------------
/examples/socket-channel/local.js:
--------------------------------------------------------------------------------
1 | const dispatcher = new window.EventDispatcher();
2 | const signalling = new window.SocketChannel(dispatcher, 'http://localhost:3000');
3 |
4 | // Set up servers
5 | const servers = {
6 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }],
7 | };
8 |
9 | const peerData = new window.PeerData(dispatcher, servers);
10 | let room = null;
11 |
12 | // get video/voice stream
13 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {});
14 |
15 | function gotMedia(stream) {
16 | window.stream = stream; // make variable available to browser console
17 |
18 | const video = document.querySelector("#localVideo");
19 | video.srcObject = stream;
20 | }
21 |
22 | async function connect(e) {
23 | if (room) {
24 | return;
25 | }
26 |
27 | // share our stream
28 | room = peerData.connect("test-room", window.stream);
29 | room
30 | // you can catch errors here to know if the peer connection init failed
31 | .on("error", (event) => console.error("local:error", event))
32 | .on("participant", (participant) => {
33 | // handle this participant error
34 | participant.on("error", (event) => console.error("participant:error", event));
35 |
36 | //this peer shared a stream
37 | participant.on("track", (event) => {
38 | console.log("local:track", event);
39 |
40 | const video = document.querySelector("#remoteVideo");
41 | if (video.srcObject !== event.streams[0]) {
42 | video.srcObject = event.streams[0];
43 | }
44 | });
45 | });
46 | }
47 |
48 | async function disconnect(e) {
49 | if (room) {
50 | room.disconnect();
51 | console.log('btn:disconnect');
52 | room = null;
53 | }
54 | }
55 |
56 | document.querySelector("#connect").addEventListener("click", (e) => connect(e));
57 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e));
58 |
--------------------------------------------------------------------------------
/website/docs/media-stream.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: media-stream
3 | title: Media Stream
4 | sidebar_label: Media Stream
5 | ---
6 |
7 | ## [Media Capture and Streams Concepts and Usage](https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API#Media_Capture_and_Streams_Concepts_and_Usage)
8 |
9 | The Media Capture and Streams API, often called the Media Streams API or simply MediaStream API, is an API related to WebRTC which provides support for streaming audio and video data.
10 | It provides the interfaces and methods for working with the streams and their constituent tracks, the constraints associated with data formats, the success and error callbacks when using the data asynchronously, and the events that are fired during the process.
11 |
12 | ## Example
13 |
14 | ```javascript
15 | // get video/voice stream
16 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {})
17 |
18 | function gotMedia (stream) {
19 | // passing stream is optional, if passed will be shared between all peers in current room
20 | const room = peerData.connect('test-room', stream);
21 |
22 | room.on("participant", participant => {
23 | //this peer shared a stream
24 | participant.on("track", event => {
25 | const stream = event.streams[0];
26 | console.log("track", event, stream);
27 | });
28 | });
29 | }
30 | ```
31 |
32 | ## Add stream to existing connection
33 | ```javascript
34 | import PeerData from 'peer-data';
35 |
36 | const servers = {
37 | iceServers: [
38 | {urls: "stun:stun.1.google.com:19302"}
39 | ]
40 | };
41 |
42 | const peerData = new PeerData(servers);
43 | const room = peerData.connect('test-room');
44 |
45 | room.on("participant", participant => {
46 | navigator.mediaDevices
47 | .getUserMedia({video: true})
48 | .then(stream => {
49 | participant.addStream(stream);
50 | participant.renegotiate();
51 | });
52 | });
53 | ```
--------------------------------------------------------------------------------
/examples/local-connection/local.js:
--------------------------------------------------------------------------------
1 | // Custom signaling system (we do not built in socket.io for local example)
2 | window.localDispatcher.register("send", (event) => {
3 | console.log("localDispatcher:send", event);
4 | window.remoteDispatcher.dispatch(event.type, event);
5 | });
6 |
7 | // Set up servers
8 | const servers = {
9 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }],
10 | };
11 |
12 | const peerData = new window.PeerData(window.localDispatcher, servers);
13 | let room = null;
14 |
15 | // get video/voice stream
16 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {});
17 |
18 | function gotMedia(stream) {
19 | window.stream = stream; // make variable available to browser console
20 |
21 | const video = document.querySelector("#localVideo");
22 | video.srcObject = stream;
23 | }
24 |
25 | async function connect(e) {
26 | if (room) {
27 | return;
28 | }
29 |
30 | // share our stream
31 | room = peerData.connect("test-room", window.stream);
32 | room
33 | // you can catch errors here to know if the peer connection init failed
34 | .on("error", (event) => console.error("local:error", event))
35 | .on("participant", (participant) => {
36 | // handle this participant error
37 | participant.on("error", (event) => console.error("participant:error", event));
38 |
39 | //this peer shared a stream
40 | participant.on("track", (event) => {
41 | console.log("local:track", event);
42 |
43 | const video = document.querySelector("#remoteVideo");
44 | if (video.srcObject !== event.streams[0]) {
45 | video.srcObject = event.streams[0];
46 | }
47 | });
48 | });
49 | }
50 |
51 | async function disconnect(e) {
52 | if (room) {
53 | room.disconnect();
54 | console.log('btn:disconnect');
55 | room = null;
56 | }
57 | }
58 |
59 | document.querySelector("#connect").addEventListener("click", (e) => connect(e));
60 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e));
61 |
--------------------------------------------------------------------------------
/src/app/App.ts:
--------------------------------------------------------------------------------
1 | import { EventDispatcher } from './EventDispatcher';
2 | import { SignalingEvent, SignalingEventType } from './Signaling';
3 | import { Configuration } from './Configuration';
4 | import { Room } from './Room';
5 |
6 | export class App {
7 | private dispatcher: EventDispatcher;
8 | private configuration: Configuration = new Configuration();
9 | private rooms: Map = new Map();
10 |
11 | constructor(dispatcher: EventDispatcher, servers: RTCConfiguration = {}, dataConstraints?: RTCDataChannelInit) {
12 | this.dispatcher = dispatcher;
13 |
14 | this.configuration.setServers(servers);
15 |
16 | if (dataConstraints) { this.configuration.setDataConstraints(dataConstraints); }
17 |
18 | this.dispatcher.register(SignalingEventType.CONNECT, this.onEvent);
19 | this.dispatcher.register(SignalingEventType.OFFER, this.onEvent);
20 | this.dispatcher.register(SignalingEventType.DISCONNECT, this.onEvent);
21 | this.dispatcher.register(SignalingEventType.ANSWER, this.onEvent);
22 | this.dispatcher.register(SignalingEventType.CANDIDATE, this.onEvent);
23 | this.dispatcher.register('send', this.onDisconnected);
24 | }
25 |
26 | getEventDispatcher = (): EventDispatcher => this.dispatcher;
27 |
28 | getConfiguration = (): Configuration => this.configuration;
29 |
30 | connect = (id: string, stream?: MediaStream): Room => {
31 | if (this.rooms.has(id)) {
32 | return this.rooms.get(id) as Room;
33 | }
34 |
35 | const room = new Room(id, this.configuration, this.dispatcher, stream);
36 | this.rooms.set(id, room);
37 |
38 | return room;
39 | };
40 |
41 | private onEvent = (event: SignalingEvent): App => {
42 | if (this.rooms.has(event.room.id)) {
43 | const room = (this.rooms.get(event.room.id) as Room);
44 |
45 | room.onSignalingEvent(event);
46 | }
47 |
48 | return this;
49 | };
50 |
51 | private onDisconnected = (event: SignalingEvent): void => {
52 | if (event.type === SignalingEventType.DISCONNECT) {
53 | this.rooms.delete(event.room.id);
54 | }
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/website/src/pages/en/help.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require("react");
9 |
10 | const CompLibrary = require("../../core/CompLibrary.js");
11 |
12 | const Container = CompLibrary.Container;
13 | const GridBlock = CompLibrary.GridBlock;
14 |
15 | function Help(props) {
16 | const { config: siteConfig, language = "" } = props;
17 | const { baseUrl, docsUrl } = siteConfig;
18 | const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`;
19 | const langPart = `${language ? `${language}/` : ""}`;
20 | const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`;
21 |
22 | const supportLinks = [
23 | {
24 | content: `Learn more using the [documentation on this site.](${docUrl(
25 | "installation.html"
26 | )})`,
27 | title: "Browse Docs"
28 | },
29 | {
30 | content:
31 | "[Ask questions](https://github.com/vardius/peer-data/issues) about the documentation and project",
32 | title: "Join the community"
33 | },
34 | {
35 | content:
36 | "Find out [what's new](https://github.com/vardius/peer-data/watchers) with this project",
37 | title: "Stay up to date"
38 | },
39 | {
40 | content:
41 | "Consider support this project by [sponsoring](https://github.com/sponsors/vardius)",
42 | title: "Support"
43 | },
44 | {
45 | content:
46 | "Contribute by [forking](https://github.com/vardius/peer-data/network/members) and improving this project",
47 | title: "Contribute"
48 | }
49 | ];
50 |
51 | return (
52 |
53 |
54 |
55 |
56 |
Need help?
57 |
58 |
This project is maintained by a dedicated group of people.
59 |
60 |
61 |
62 |
63 | );
64 | }
65 |
66 | module.exports = Help;
67 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We are open to, and grateful for, any contributions made by the community. By contributing to **peer-data**, you agree to abide by the [code of conduct](https://github.com/vardius/peer-data/blob/master/CODE_OF_CONDUCT.md).
4 |
5 | ## Reporting Issues and Asking Questions
6 |
7 | Before opening an issue, please search the [issue tracker](https://github.com/vardius/peer-data/issues) to make sure your issue hasn't already been reported.
8 |
9 | ### Bugs and Improvements
10 |
11 | We use the issue tracker to keep track of bugs and improvements to **peer-data** itself, its examples, and the documentation. We encourage you to open issues to discuss improvements, architecture, theory, internal implementation, etc. If a topic has been discussed before, we will ask you to join the previous discussion.
12 |
13 | Any pull requests that involve breaking changes should be made against the `next` branch.
14 |
15 | ### Getting Help
16 |
17 | For support or usage questions like “how do I do X with **peer-data**” and “my code doesn't work”, we encourage you to post an issue.
18 |
19 | Please be considerate when doing this as this is not the primary purpose of the issue tracker.
20 |
21 | ## Development
22 |
23 | Visit the [issue tracker](https://github.com/vardius/peer-data/issues) to find a list of open issues that need attention.
24 |
25 | Fork, then clone the repo:
26 |
27 | ```
28 | git clone https://github.com/your-username/peer-data.git
29 | ```
30 |
31 | ### Docs
32 |
33 | Improvements to the documentation are always welcome. In the docs we abide by typographic rules, so instead of ' you should use '. Same goes for “ ” and dashes (—) where appropriate. These rules only apply to the text, not to code blocks.
34 |
35 | ### Sending a Pull Request
36 |
37 | For non-trivial changes, please open an issue with a proposal for a new feature or refactoring before starting on the work. We don't want you to waste your efforts on a pull request that we won't want to accept.
38 |
39 | On the other hand, sometimes the best way to start a conversation *is* to send a pull request. Use your best judgement!
40 |
41 | In general, the contribution workflow looks like this:
42 |
43 | * Open a new issue in the [Issue tracker](https://github.com/vardius/peer-data/issues).
44 | * Fork the repo.
45 | * Create a new feature branch based off the `master` branch.
46 | * Make sure all tests pass and there are no linting errors.
47 | * Submit a pull request, referencing any issues it addresses.
48 |
49 | Please try to keep your pull request focused in scope and avoid including unrelated commits.
50 |
51 | After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements.
52 |
53 | Thank you for contributing!
54 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "peer-data",
3 | "version": "3.2.5",
4 | "description": "PeerData - library for files, media streaming/sharing using WebRTC",
5 | "scripts": {
6 | "build": "rollup -c",
7 | "clean": "rimraf dist coverage",
8 | "typecheck": "tsc --noEmit",
9 | "lint": "eslint -c .eslintrc.js --ext .ts src",
10 | "test": "jest --no-cache",
11 | "test:cov": "yarn test -- --coverage",
12 | "test:watch": "yarn test -- --watchAll",
13 | "prepare": "yarn build",
14 | "prebuild": "yarn clean",
15 | "postbuild": "rimraf dist/**/__tests__",
16 | "posttest": "yarn typecheck && yarn lint",
17 | "preversion": "yarn test",
18 | "postversion": "git push && git push --tags",
19 | "check": "npm-check -u"
20 | },
21 | "main": "dist/index.js",
22 | "module": "dist/index.es.js",
23 | "jsnext:main": "dist/index.es.js",
24 | "types": "dist/index.d.ts",
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/vardius/peer-data.git"
28 | },
29 | "files": [
30 | "dist"
31 | ],
32 | "keywords": [
33 | "PeerData",
34 | "WebRTC",
35 | "cdn",
36 | "web",
37 | "rtc",
38 | "video",
39 | "player",
40 | "html5",
41 | "peer",
42 | "socket",
43 | "real",
44 | "time",
45 | "communication"
46 | ],
47 | "author": {
48 | "name": "Rafał Lorenz",
49 | "email": "vardius@gmail.com"
50 | },
51 | "license": "MIT",
52 | "bugs": {
53 | "url": "https://github.com/vardius/peer-data/issues"
54 | },
55 | "homepage": "https://github.com/vardius/peer-data#readme",
56 | "jest": {
57 | "transform": {
58 | ".(ts?)": "ts-jest"
59 | },
60 | "testMatch": [
61 | "**/?(*.)(spec|test).{t,j}s"
62 | ],
63 | "testPathIgnorePatterns": [
64 | "/(node_modules|lib|es|dist)"
65 | ],
66 | "collectCoverageFrom": [
67 | "src/**/*.{t,j}s",
68 | "!src/**/*.d.ts"
69 | ],
70 | "moduleFileExtensions": [
71 | "js",
72 | "json",
73 | "ts"
74 | ]
75 | },
76 | "peerDependencies": {
77 | "webrtc-adapter": "^7.2.3"
78 | },
79 | "dependencies": {
80 | "@types/uuid": "^8.0.0",
81 | "socket.io-client": "^2.3.0",
82 | "uuid": "^8.1.0"
83 | },
84 | "devDependencies": {
85 | "@rollup/plugin-commonjs": "^11.0.2",
86 | "@rollup/plugin-node-resolve": "^7.1.1",
87 | "@types/jest": "^25.1.2",
88 | "@types/node": "^13.7.0",
89 | "@types/socket.io-client": "^1.4.29",
90 | "@types/webrtc": "0.0.25",
91 | "@typescript-eslint/eslint-plugin": "^2.19.0",
92 | "@typescript-eslint/parser": "^2.19.0",
93 | "codecov": "^3.6.5",
94 | "cross-env": "^7.0.0",
95 | "dts-bundle": "^0.7.3",
96 | "eslint": "^6.8.0",
97 | "jest": "^25.1.0",
98 | "jest-cli": "^25.1.0",
99 | "jest-environment-node-debug": "^2.0.0",
100 | "npm-check": "^5.7.1",
101 | "rimraf": "^3.0.1",
102 | "rollup": "^1.31.0",
103 | "rollup-plugin-sourcemaps": "^0.5.0",
104 | "rollup-plugin-typescript2": "^0.25.3",
105 | "ts-jest": "^25.2.0",
106 | "tslib": "^1.10.0",
107 | "typescript": "^3.7.5"
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PeerData
2 | [](https://travis-ci.org/vardius/peer-data)
3 | [](https://www.npmjs.com/package/peer-data)
4 | [](https://www.npmjs.com/package/peer-data)
5 | [](LICENSE)
6 |
7 |
8 |
9 |
10 | PeerData is a library for bidirectional peer-to-peer transfers of arbitrary data using [RTCDataChannel](https://developer.mozilla.org/pl/docs/Web/API/RTCDataChannel). Simple *WebRTC* wrapper providing data channel abstraction.
11 |
12 | [WebRTC](https://webrtc.org/) needs a messaging service to set up and maintain a *WebRTC* call.
13 |
14 | The sender and receiver *RTCPeerConnections* run in web pages on different devices, and we need a way for them to communicate metadata.
15 | For this, we use a signaling server: a server that can pass messages between *WebRTC* clients (peers).
16 |
17 | [PeerDataServer](https://github.com/vardius/peer-data-server) - An **ready to use** example of signaling server on *Node* using [socket.io](http://socket.io/).
18 |
19 | 📖 ABOUT
20 | ==================================================
21 | Contributors:
22 |
23 | * [Rafał Lorenz](https://rafallorenz.com)
24 |
25 | Want to contribute ? Feel free to send pull requests!
26 |
27 | Have problems, bugs, feature ideas?
28 | We are using the github [issue tracker](https://github.com/vardius/peer-data/issues) to manage them.
29 |
30 | ## 📚 Documentation
31 |
32 | For **documentation** (_including examples_), **visit [rafallorenz.com/peer-data](https://rafallorenz.com/peer-data)**
33 |
34 | 🚏 HOW TO USE
35 | ==================================================
36 |
37 | 1. [Chat Example](https://github.com/vardius/webrtc-chat)
38 | 2. [React Chat Example](https://github.com/vardius/react-webrtc-chat)
39 | 3. [React Hook](https://github.com/vardius/react-peer-data)
40 |
41 | ## Installation
42 | ```bash
43 | $ npm install peer-data
44 | ```
45 |
46 | ## Basic example
47 | ```typescript
48 | import PeerData, { EventDispatcher, SocketChannel } from 'peer-data';
49 |
50 | const constraints = {ordered: true};
51 | const servers = {
52 | iceServers: [
53 | {urls: "stun:stun.1.google.com:19302"}
54 | ]
55 | };
56 |
57 | const dispatcher = new EventDispatcher();
58 | const peerData = new PeerData(dispatcher, servers, constraints);
59 | const signaling = new SocketChannel(dispatcher, 'http://localhost:8080');
60 |
61 | const room = peerData.connect('test-room');
62 |
63 | room.on("participant", participant => {
64 | participant.on("message", payload => console.log("message", payload));
65 |
66 | participant.send('Hi mate! this is private message.');
67 | })
68 | ```
69 |
70 | For how to **disconnect**, **close connection** and handle errors please check [documentation](https://rafallorenz.com/peer-data/docs/client).
71 |
72 | 📜 [License](LICENSE.md)
73 | -------
74 |
75 | This package is released under the MIT license. See the complete license in the package
76 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vardius@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/website/src/core/Footer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require("react");
9 |
10 | class Footer extends React.Component {
11 | docUrl(doc, language) {
12 | const baseUrl = this.props.config.baseUrl;
13 | const docsUrl = this.props.config.docsUrl;
14 | const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`;
15 | const langPart = `${language ? `${language}/` : ""}`;
16 | return `${baseUrl}${docsPart}${langPart}${doc}`;
17 | }
18 |
19 | pageUrl(doc, language) {
20 | const baseUrl = this.props.config.baseUrl;
21 | return baseUrl + (language ? `${language}/` : "") + doc;
22 | }
23 |
24 | render() {
25 | return (
26 |
95 | );
96 | }
97 | }
98 |
99 | module.exports = Footer;
100 |
--------------------------------------------------------------------------------
/examples/local-connection/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | PeerData - local connection example
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |