Michelle Bu пре 11 година
родитељ
комит
39dafc1895
5 измењених фајлова са 434 додато и 0 уклоњено
  1. 4 0
      docs/Makefile
  2. 13 0
      docs/build_docs.js
  3. 298 0
      docs/index.html
  4. 19 0
      docs/package.json
  5. 100 0
      docs/template.html

+ 4 - 0
docs/Makefile

@@ -0,0 +1,4 @@
+default: build
+
+build:
+	@node ./build_docs.js

+ 13 - 0
docs/build_docs.js

@@ -0,0 +1,13 @@
+var markdown = require('markdown').markdown;
+var handlebars = require('handlebars');
+var fs = require('fs');
+
+var data = {
+  apiHTML: markdown.toHTML(fs.readFileSync('./api.md', {encoding: 'utf8'})),
+  //startHTML: fs.readFileSync('./start.md', {encoding: 'utf8'})
+};
+
+var templateFile = fs.readFileSync('./template.html', {encoding: 'utf8'});
+var template = handlebars.compile(templateFile);
+
+fs.writeFile('./index.html', template(data));

+ 298 - 0
docs/index.html

@@ -0,0 +1,298 @@
+<head>
+  <link href="/style.css" rel="stylesheet" type="text/css">
+  <script type="text/javascript" src="/index.js"></script>
+</head>
+
+<body>
+  <section class="api">
+
+    <h1>PeerJS API Reference</h1>
+
+<p><strong>Due to browsers&#39; incomplete support of the WebRTC DataChannel specification, many features of PeerJS have caveats.
+<a href="http://peerjs.com/status">View the status page for full details</a>.</strong></p>
+
+<ul><li><a href="#class-peerjspeer">Class: peerjs.Peer</a><ul><li><a href="#new-peerid-options">new Peer([id], [options])</a></li><li><a href="#peerbrowser">Peer.browser</a></li><li><a href="#peerid">peer.id</a></li><li><a href="#peerconnections">peer.connections</a></li><li><a href="#peerconnectid-options">peer.connect(id, [options])</a></li><li><a href="#peerdestroy">peer.destroy()</a></li><li><a href="#peerdisconnect">peer.disconnect()</a></li><li><a href="#peerdisconnected">peer.disconnected</a></li><li><a href="#peerdestroyed">peer.destroyed</a></li><li><a href="#event-connection">Event: &#39;connection&#39;</a></li><li><a href="#event-open">Event: &#39;open&#39;</a></li><li><a href="#event-error">Event: &#39;error&#39;</a></li><li><a href="#event-close">Event: &#39;close&#39;</a></li></ul></li><li><a href="#class-peerjsdataconnection">Class: peerjs.DataConnection</a><ul><li><a href="#experimental-reliable-and-large-file-transfer">EXPERIMENTAL reliable and large file transfer:</a></li><li><a href="#connectionpeer">connection.peer</a></li><li><a href="#connectionopen">connection.open</a></li><li><a href="#connectionmetadata">connection.metadata</a></li><li><a href="#connectionlabel">connection.label</a></li><li><a href="#connectionserialization">connection.serialization</a></li><li><a href="#connectionsenddata">connection.send(data)</a></li><li><a href="#connectionclose">connection.close()</a></li><li><a href="#event-data">Event: &#39;data&#39;</a></li><li><a href="#event-open-1">Event: &#39;open&#39;</a></li><li><a href="#event-error-1">Event: &#39;error&#39;</a></li><li><a href="#event-close-1">Event: &#39;close&#39;</a></li></ul></li></ul>
+
+<h2>Class: peerjs.Peer</h2>
+
+<p>This class is a Peer, which can connect to other peers and listen for connections. It is an <code>EventEmitter</code>.</p>
+
+<h3>new Peer([id], [options])</h3>
+
+<ul><li><code>id</code> String. The id by which this peer will be identified when other peers try to connect to it. If no id is given, one will be generated by the server. <strong>Note that this ID is mainly used for brokering and that it is not recommended that you use it to identify peers. Also note that you can set a <code>metadata</code> option to send other identifying information.</strong></li><li><code>options</code> Object<ul><li><code>key</code> String. API key for cloud PeerServer. Is not used for servers other than <code>cloud.peerjs.com</code></li><li><code>host</code> String. Server host. Default <code>cloud.peerjs.com</code>. Also accepts <code>&#39;/&#39;</code> for relative hostname.</li><li><code>port</code> Number. Server port. Default <code>80</code></li><li><code>config</code> Object. Configuration hash passed to <code>RTCPeerConnection</code>. This hash contains the ICE servers. Default <code>{ &#39;iceServers&#39;: [{ &#39;url&#39;: &#39;stun:stun.l.google.com:19302&#39; }] }</code></li><li><code>debug</code> Boolean. Prints verbose log messages. Default <code>false</code> </li></ul></li></ul>
+
+<p>Construct a new Peer object.</p>
+
+<p>The Peer object is used to connect to other Peer clients and also to receive connections from other clients.</p>
+
+<p>The first argument is the id that other peers will use to connect to this peer, thus it must be unique for the given <code>key</code> (if you&#39;re using PeerServer cloud) or server.</p>
+
+<p>In the options, either a PeerServer Cloud <code>key</code> must be provided or <code>host</code> and <code>port</code> for your own PeerServer. <strong>Note that the server is only for brokering connections and does not proxy data between peers.</strong></p>
+
+<p>The <code>config</code> object is passed straight into instances of <code>RTCPeerConnection</code>. For compatibility with symmetric NATs, you can provide your own TURN server. By default the STUN server provided by Google is used.</p>
+
+<h3>Peer.browser</h3>
+
+<p>The type of browser the client is on. Currently WebRTC DataChannels are not
+interoperable so different browser types should not be connected.</p>
+
+<h3>peer.id</h3>
+
+<p>The given id of this peer.</p>
+
+<p>If no id was specified in the constructor, this value will be <code>undefined</code> util the <code>open</code> event fires.</p>
+
+<h3>peer.connections</h3>
+
+<p>A hash of all current connections with the current peer. Keys are ids and values are hashes of label =&gt; <code>DataConnection</code> pairs.</p>
+
+<p><strong>You are recommended to keep track of connections yourself rather than to manipulate this hash.</strong></p>
+
+<h3>peer.connect(id, [options])</h3>
+
+<p>Connects to the remote peer specified by <code>id</code>.</p>
+
+<p>This function can be called multiple times for multiplexed connections between
+two peers. In Firefox however this functionality is only available before the
+first connection is established.</p>
+
+<p>Returns a <code>DataConnection</code> object.</p>
+
+<ul><li><code>id</code> String. The id of the remote peer to connect to.</li><li><code>options</code> Object.<ul><li><code>label</code> Optional label for the underlying DataChannel, to differentiate between DataConnections between the same two peers. If left unspecified, a label will be assigned at random.</li><li><code>metadata</code> Optional metadata to pass to the remote peer. Can be any serializable type.</li><li><code>serialization</code> String, which can be <code>binary</code>, <code>binary-utf8</code>, <code>json</code>, or <code>none</code>. This will be the serialization format of all data sent over the P2P DataConnection. Defaults to <code>binary</code>.</li><li><code>reliable</code> Boolean, which if <code>true</code> activates experimental reliable transfer in Chrome (while waiting for actual reliable transfer to be implemented in Chrome). Defaults to <code>false</code> until Chrome implements reliable/large data transfer. Defaults to true in Firefox.</li></ul></li></ul>
+
+<p>Before writing to / data will be emitted from the <code>DataConnection</code> object that is returned, the <code>open</code> event must fire. Also the <code>error</code> event should be checked in case a connection cannot be made.</p>
+
+<h3>peer.destroy()</h3>
+
+<p>Close the connection to the server and terminate all connections.</p>
+
+<p><strong>Warning: This cannot be undone; the respective peer object will no longer be able to create or receive any connections and its ID will be forfeited on the (cloud) server.</strong></p>
+
+<h3>peer.disconnect()</h3>
+
+<p>Close the connection to the server, leaving all existing DataConnections intact.</p>
+
+<p><strong>Warning: This cannot be undone; the respective peer object will no longer be able to create or receive any connections and its ID will be forfeited on the (cloud) server.</strong></p>
+
+<h3>peer.disconnected</h3>
+
+<p>Is false if there is an active connection to the PeerServer.</p>
+
+<h3>peer.destroyed</h3>
+
+<p>Is true if this peer is destroyed and can no longer be used.</p>
+
+<h3>Event: &#39;connection&#39;</h3>
+
+<p><code>function (connection, meta) { }</code></p>
+
+<p>When a new connection is established from another peer to this peer, the <code>DataConnection</code> object is emitted with this event. The <code>meta</code> argument contains whatever metadata values passed into <code>peer.connection(...)</code> by the remote peer.</p>
+
+<p><strong>Note:</strong> the <code>open</code> event must fire on the <code>DataConnection</code> before it is ready to read/write.</p>
+
+<h3>Event: &#39;open&#39;</h3>
+
+<p><code>function(id) { }</code></p>
+
+<p>Fired when the PeerServer connection is succesfully, fully, open.
+This event does not need to fire before creating or receiving connections.
+<strong>You should not wait for open before connecting to other peers or expecting to receive connections if connection speed is important.</strong></p>
+
+<p><code>id</code> is the id of this <code>Peer</code> object, either provided in the constructor, or generated automatically by the PeerServer.</p>
+
+<h3>Event: &#39;error&#39;</h3>
+
+<p><code>function (error) { }</code></p>
+
+<p>Emitted when an unexpected event occurs. Errors on the Peer are <strong>always
+fatal</strong>. Errors from the underlying socket and PeerConnections are forwarded here.</p>
+
+<p>The <code>error</code> object also has a <code>type</code> parameter that may be helpful in responding to client errors properly:
+<em> <code>browser-incompatible</code>: The client&#39;s browser does not support some or all WebRTC features that you are trying to use.
+</em> <code>invalid-id</code>: The ID passed into the Peer constructor contains illegal characters.
+<em> <code>invalid-key</code>: The API key passed into the Peer constructor contains illegal characters or is not in the system (cloud server only).
+</em> <code>unavailable-id</code>: The ID passed into the Peer constructor is already taken.
+<em> <code>firefoxism</code>: The operation you&#39;re trying to perform is not supported in firefox.
+</em> <code>ssl-unavailable</code>: PeerJS is being used securely, but the cloud server does not support SSL. Use a custom PeerServer.
+<em> Errors types that shouldn&#39;t regularly appear:
+  </em> <code>server-error</code>: Unable to reach the server.
+  <em> <code>socket-error</code>: An error from the underlying socket.
+  </em> <code>socket-closed</code>: The underlying socket closed unexpectedly.
+<em> (The Peer object is destroyed after one of the errors above are emitted.)
+</em> <code>server-disconnected</code>: A Peer that has been disconnected is being used to try to connect.</p>
+
+<h3>Event: &#39;close&#39;</h3>
+
+<p><code>function () { }</code></p>
+
+<p>Emitted when the Peer object has closed its connection with PeerServer so no more remote peer connections can be made or received.</p>
+
+<p>To be extra certain that Peer objects clean up cleanly (and because it takes the WS server and DataChannel some time to realize that a Peer has disconnected), it is best to call <code>destroy()</code> on a Peer when it is no longer needed.</p>
+
+<h2>Class: peerjs.DataConnection</h2>
+
+<p>This class is the interface two communicate between two peers. It is an <code>EventEmitter</code>.</p>
+
+<p>There is no constructor. A <code>DataConnection</code> object must be obtained in the callback of <code>peer.connect(...)</code> when initiating a peer-to-peer connection or emitted in the <code>peer.on(&#39;connection&#39;, ...)</code> event when receiving a connection.</p>
+
+<h3>EXPERIMENTAL reliable and large file transfer:</h3>
+
+<p>(CHROME ONLY. Firefox has reliable transport built in and reliable transfer is the default option.) Simply pass in <code>reliable: true</code> when calling <code>.connect(...)</code>. This module is experimental, temporary, and exists here: https://github.com/michellebu/reliable</p>
+
+<p><em>Caveat:</em> With reliable enabled in Chrome, you can no longer customize the serialization format used for data transfer.</p>
+
+<h3>connection.peer</h3>
+
+<p>The id of the remote peer this connection is connected to.</p>
+
+<h3>connection.open</h3>
+
+<p>Whether the connection is open (ready for read and write).</p>
+
+<h3>connection.metadata</h3>
+
+<p>The metadata passed in when the connection was created with <code>peer.connect(...)</code>.</p>
+
+<h3>connection.label</h3>
+
+<p>The optional label passed in or assigned by PeerJS when the connection was created with <code>peer.connect(...)</code>.</p>
+
+<h3>connection.serialization</h3>
+
+<p>The serialization format of the connection. Can be <code>binary</code>, <code>binary-utf8</code>, <code>json</code>, or <code>none</code>
+for no serialization. Default serialization format is <code>binary</code>.</p>
+
+<p><strong>Note:</strong> <code>binary-utf8</code> will take a performance hit because of the way utf8 strings are packed into binary.</p>
+
+<h3>connection.send(data)</h3>
+
+<p>Accepts data of any JSON type or binary type.</p>
+
+<p>To configure which serialization format to use, specify <code>binary</code>, <code>binary-utf8</code>, <code>json</code>, or <code>none</code> as the <code>serialization</code> property of the <code>options</code> object in <code>peer.connect(...)</code>.</p>
+
+<p>Data is serialized using BinaryPack (<code>binary</code>) by default and then sent to the remote peer.</p>
+
+<h3>connection.close()</h3>
+
+<p>Gracefully closes the connection.</p>
+
+<h3>Event: &#39;data&#39;</h3>
+
+<p><code>function (data) { }</code></p>
+
+<p>Emitted when data is received from the remote peer. </p>
+
+<p>The <code>data</code> parameter contains values exactly as put into the <code>connection.send(...)</code>. Binary types will have been deserialized to <code>ArrayBuffer</code>.</p>
+
+<h3>Event: &#39;open&#39;</h3>
+
+<p><code>function () { }</code></p>
+
+<p>Emitted when the connection is established and ready for writing. <code>data</code> from the remote peer will also start to be emitted.</p>
+
+<h3>Event: &#39;error&#39;</h3>
+
+<p><code>function (error) { }</code></p>
+
+<p>If the connection emits an error, this event is emitted (errors from the underlying <code>DataChannel</code> are forwarded here).</p>
+
+<p><code>error</code> is an <code>Error</code> object.</p>
+
+<h3>Event: &#39;close&#39;</h3>
+
+<p><code>function () { }</code></p>
+
+<p>Is emitted when the connection is closed.</p>
+
+<p>The <code>close</code> event is also emitted when the remote peer closes the connection.</p>
+
+  </section>
+
+  <section class="start">
+    <h2>Get started with PeerJS</h2>
+
+      <div class="warning">Due to browsers' incomplete support of the WebRTC DataChannel specification, many features of PeerJS have caveats.<br><a href="/status">View the status page for full details</a>.</div>
+      <p>PeerJS requires two components: the PeerJS client library and the PeerServer.</p>
+
+    <h2>PeerServer</h2>
+
+      <p>The PeerServer brokers connections between PeerJS clients. Once two clients have established a connection with each other with the PeerServer's help, data is will flow between the clients directly.</p>
+      <p>Choose one of the following options:</p>
+      <p><a href="/peerserver">Sign up for free cloud-hosted PeerServer service</a></p>
+      <p>Alternatively, <a href="http://github.com/peers/peerjs-server">PeerServer is
+      available on GitHub</a> and on <a href="https://npmjs.org/package/peer">npm</a>:</a>
+      <pre><code>npm install peer</code></pre>
+      <p>Setting up the server on your own is just a few lines of code:</a>
+      <pre><code>var PeerServer = require('peer').PeerServer;
+      var server = new PeerServer({ port: 9000 });</code></pre>
+
+    <h2>PeerJS Client</h2>
+
+      <p>The client is where all the action is at.<p>
+      <h3>1. Include the PeerJS client in your frontend Javascript code:</h3>
+      <pre><code>&lt;script src="http://cdn.peerjs.com/0/peer.min.js"&gt;&lt;/script&gt;
+      </code></pre>
+      <h3>2. Create the Peer object.</h3>
+      <p>
+      You'll need to provide an ID. When other peers try to connect to you, they'll have to know this ID.</p>
+      <p>
+      Also you'll need to provide either the API key for your PeerServer cloud account or your own PeerServer:
+      </p>
+      <pre><code>var peer = new Peer('some-id', {key: 'myapikey'});
+      </code></pre>
+      <p>Or if you're running your own PeerServer</p>
+      <pre><code>var peer = new Peer('some-id', {host: 'localhost', port: 9000});
+      </code></pre>
+      <h3>3. That's it! You're ready to send and receive binary P2P data connections!</h3>
+      <p>Listening for incoming connections:</p>
+      <pre><code>peer.on('connection', function(conn){
+        conn.on('data', function(data) {
+          console.log('Got data:', data);
+        });
+      });
+      </code></pre>
+
+      <p>Create a peer connection:</p>
+      <pre><code>var conn = peer.connect('some-id');
+      conn.on('open', function() {
+        conn.send('Hello world!');
+      });
+      </code></pre>
+
+    <h2>Other cool things you need to know</h2>
+
+      <h3>What kind of data can I send?</h3>
+
+        <p>PeerJS has the BinaryPack serialization format built-in. This means you can send any JSON type as well as binary Blobs and ArrayBuffers. You don't have to worry about serializing yourself. Simple put objects in on one side and get objects out on the other:</p>
+        <pre><code>conn.send({
+          strings: 'hi!',
+          numbers: 150,
+          arrays: [1,2,3],
+          evenbinary: new Blob([1,2,3]),
+          andmore: {bool: true}
+        });
+        </code></pre>
+        <p>With BinaryPack, the data is never converted to strings. Everything is binary end-to-end. This results in bandwidth savings.
+        </p>
+
+      <h3>Preconnection</h3>
+
+        <p>When you try to connect to a peer, PeerServer will hold a connection offer for up to 5 seconds before rejecting it. This is useful if you want to reconnect to a peer as it disconnects and reconnects rapidly between web pages.</p>
+
+      <h3>Connection latency/bandwidth</h3>
+
+        <p>Data sent between the two peers do not touch any other servers, so the connection speed is limited only by the upload and download rates of the two peers. This also means you don't have the additional latency of an intermediary server.</p>
+        <p>The latency to establish a connection is identified by two factors: the brokering of data and identifying of clients. PeerJS has been carefully coded to minimize latency in both applications. Data is brokered through an XHR streaming request before a WebSocket connection is established, then through WebSocket afterwards. Identity is self-provided and thus a new client can report identity, accept an outstanding offer, and and provide answer and thus establish the peer-to-peer connection in very few RTTs.</p>
+        <p>Note that in the infrequent case that both peers are behind symmetric NATs, this is no longer true. See below.</p>
+
+      <h3>Peer-to-peer shortingcomings</h3>
+
+        <p>A very low percentage of users are behind symmetric NATs. When two symmetric NAT users try to connect to each other, NAT traversal is impossible and no connection can be made. A workaround is to proxy through what is known as a TURN server. The PeerServer cloud service does not provide a TURN server. You'll have to find your own. You can pass a TURN server into the <tt>Peer</tt> object options. This will allow your PeerJS app to work seamlessly for this situation</p>
+
+      <h3>Current state of browser compatibility</h3>
+
+        <p><a href="/status">Detailed browser compatibility information</a></p>
+        <p><a href="https://groups.google.com/forum/?fromgroups#!forum/peerjs">Discuss PeerJS on our Google Group</a></p>
+
+  </section>
+</body>

+ 19 - 0
docs/package.json

@@ -0,0 +1,19 @@
+{
+  "author": "Michelle Bu <michellebu@berkeley.edu>",
+  "name": "peerjs-docs",
+  "description": "PeerJS documentation",
+  "version": "0.2.8-60-gae41079",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/peers/peerjs.git"
+  },
+  "dependencies": {
+    "markdown": "~0.5.0",
+    "handlebars": "~1.0.12"
+  },
+  "devDependencies": {},
+  "optionalDependencies": {},
+  "engines": {
+    "node": "*"
+  }
+}

+ 100 - 0
docs/template.html

@@ -0,0 +1,100 @@
+<head>
+  <link href="/style.css" rel="stylesheet" type="text/css">
+  <script type="text/javascript" src="/index.js"></script>
+</head>
+
+<body>
+  <section class="api">
+
+    {{{apiHTML}}}
+
+  </section>
+
+  <section class="start">
+    <h2>Get started with PeerJS</h2>
+
+      <div class="warning">Due to browsers' incomplete support of the WebRTC DataChannel specification, many features of PeerJS have caveats.<br><a href="/status">View the status page for full details</a>.</div>
+      <p>PeerJS requires two components: the PeerJS client library and the PeerServer.</p>
+
+    <h2>PeerServer</h2>
+
+      <p>The PeerServer brokers connections between PeerJS clients. Once two clients have established a connection with each other with the PeerServer's help, data is will flow between the clients directly.</p>
+      <p>Choose one of the following options:</p>
+      <p><a href="/peerserver">Sign up for free cloud-hosted PeerServer service</a></p>
+      <p>Alternatively, <a href="http://github.com/peers/peerjs-server">PeerServer is
+      available on GitHub</a> and on <a href="https://npmjs.org/package/peer">npm</a>:</a>
+      <pre><code>npm install peer</code></pre>
+      <p>Setting up the server on your own is just a few lines of code:</a>
+      <pre><code>var PeerServer = require('peer').PeerServer;
+      var server = new PeerServer({ port: 9000 });</code></pre>
+
+    <h2>PeerJS Client</h2>
+
+      <p>The client is where all the action is at.<p>
+      <h3>1. Include the PeerJS client in your frontend Javascript code:</h3>
+      <pre><code>&lt;script src="http://cdn.peerjs.com/0/peer.min.js"&gt;&lt;/script&gt;
+      </code></pre>
+      <h3>2. Create the Peer object.</h3>
+      <p>
+      You'll need to provide an ID. When other peers try to connect to you, they'll have to know this ID.</p>
+      <p>
+      Also you'll need to provide either the API key for your PeerServer cloud account or your own PeerServer:
+      </p>
+      <pre><code>var peer = new Peer('some-id', {key: 'myapikey'});
+      </code></pre>
+      <p>Or if you're running your own PeerServer</p>
+      <pre><code>var peer = new Peer('some-id', {host: 'localhost', port: 9000});
+      </code></pre>
+      <h3>3. That's it! You're ready to send and receive binary P2P data connections!</h3>
+      <p>Listening for incoming connections:</p>
+      <pre><code>peer.on('connection', function(conn){
+        conn.on('data', function(data) {
+          console.log('Got data:', data);
+        });
+      });
+      </code></pre>
+
+      <p>Create a peer connection:</p>
+      <pre><code>var conn = peer.connect('some-id');
+      conn.on('open', function() {
+        conn.send('Hello world!');
+      });
+      </code></pre>
+
+    <h2>Other cool things you need to know</h2>
+
+      <h3>What kind of data can I send?</h3>
+
+        <p>PeerJS has the BinaryPack serialization format built-in. This means you can send any JSON type as well as binary Blobs and ArrayBuffers. You don't have to worry about serializing yourself. Simple put objects in on one side and get objects out on the other:</p>
+        <pre><code>conn.send({
+          strings: 'hi!',
+          numbers: 150,
+          arrays: [1,2,3],
+          evenbinary: new Blob([1,2,3]),
+          andmore: {bool: true}
+        });
+        </code></pre>
+        <p>With BinaryPack, the data is never converted to strings. Everything is binary end-to-end. This results in bandwidth savings.
+        </p>
+
+      <h3>Preconnection</h3>
+
+        <p>When you try to connect to a peer, PeerServer will hold a connection offer for up to 5 seconds before rejecting it. This is useful if you want to reconnect to a peer as it disconnects and reconnects rapidly between web pages.</p>
+
+      <h3>Connection latency/bandwidth</h3>
+
+        <p>Data sent between the two peers do not touch any other servers, so the connection speed is limited only by the upload and download rates of the two peers. This also means you don't have the additional latency of an intermediary server.</p>
+        <p>The latency to establish a connection is identified by two factors: the brokering of data and identifying of clients. PeerJS has been carefully coded to minimize latency in both applications. Data is brokered through an XHR streaming request before a WebSocket connection is established, then through WebSocket afterwards. Identity is self-provided and thus a new client can report identity, accept an outstanding offer, and and provide answer and thus establish the peer-to-peer connection in very few RTTs.</p>
+        <p>Note that in the infrequent case that both peers are behind symmetric NATs, this is no longer true. See below.</p>
+
+      <h3>Peer-to-peer shortingcomings</h3>
+
+        <p>A very low percentage of users are behind symmetric NATs. When two symmetric NAT users try to connect to each other, NAT traversal is impossible and no connection can be made. A workaround is to proxy through what is known as a TURN server. The PeerServer cloud service does not provide a TURN server. You'll have to find your own. You can pass a TURN server into the <tt>Peer</tt> object options. This will allow your PeerJS app to work seamlessly for this situation</p>
+
+      <h3>Current state of browser compatibility</h3>
+
+        <p><a href="/status">Detailed browser compatibility information</a></p>
+        <p><a href="https://groups.google.com/forum/?fromgroups#!forum/peerjs">Discuss PeerJS on our Google Group</a></p>
+
+  </section>
+</body>