Last active
September 8, 2023 15:13
-
-
Save image72/3932ea081221ca02bf3ed9814dcd8d1b to your computer and use it in GitHub Desktop.
WebRTC peer to peer, simple codes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width" /> | |
<title>Peer-to-Peer Cue System --- Reciever</title> | |
<style> | |
body { | |
font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; | |
background-color: white; | |
min-width: 450px; | |
} | |
h1 { | |
font-size: 1.75em; | |
} | |
h2 { | |
text-align: center; | |
font-size: 4em; | |
} | |
td { | |
width: 50%; | |
} | |
input { | |
margin-bottom: 5px; | |
} | |
a:visited { | |
color: blue; | |
} | |
.display { | |
width: 100%; | |
min-height: 400px; | |
padding-bottom: 20px; | |
} | |
.control { | |
width: 100%; | |
padding-bottom: 20px; | |
} | |
.control-button { | |
width: 100%; | |
min-height: 50px; | |
} | |
.display-box { | |
border: 2px solid black; | |
} | |
.title { | |
vertical-align: top; | |
} | |
.standby { | |
background-color: red; | |
} | |
.go { | |
background-color: green; | |
} | |
.fade { | |
background-color: yellow; | |
} | |
.off { | |
background-color: gray; | |
} | |
.hidden { | |
visibility: hidden; | |
} | |
.no-display { | |
display: none; | |
} | |
.status { | |
height: 125px; | |
vertical-align: text-top; | |
font-weight: bold; | |
margin-bottom: 10px; | |
border-bottom: 2px solid black; | |
} | |
.message { | |
height: 125px; | |
max-height: 125px; | |
margin-bottom: 10px; | |
border-bottom: 2px solid black; | |
overflow: auto; | |
} | |
.msg-time { | |
color: blue; | |
} | |
.cueMsg { | |
color: orange; | |
} | |
.selfMsg { | |
color: green; | |
} | |
.peerMsg { | |
color: red; | |
} | |
</style> | |
</head> | |
<body> | |
<table class="display"> | |
<tr> | |
<td class="title">Status:</td> | |
<td class="title">Messages:</td> | |
</tr> | |
<tr> | |
<td> | |
<div id="receiver-id" style="font-weight: bold" title="Copy this ID to the input on send.html."> | |
ID: | |
</div> | |
</td> | |
<td> | |
<input type="text" id="sendMessageBox" placeholder="Enter a message..." autofocus="true" /> | |
<button type="button" id="sendButton">Send</button> | |
<button type="button" id="clearMsgsButton">Clear Msgs (Local)</button> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<div id="status" class="status"></div> | |
</td> | |
<td> | |
<div class="message" id="message"></div> | |
</td> | |
</tr> | |
<tr> | |
<td class="display-box standby" id="standby"> | |
<h2>Standby</h2> | |
</td> | |
<td class="display-box hidden" id="go"> | |
<h2>Go</h2> | |
</td> | |
</tr> | |
<tr> | |
<td class="display-box hidden" id="fade"> | |
<h2>Fade</h2> | |
</td> | |
<td class="display-box hidden" id="off"> | |
<h2>All Off</h2> | |
</td> | |
</tr> | |
</table> | |
<script src="https://unpkg.com/[email protected]/dist/peerjs.min.js"></script> | |
<script type="text/javascript"> | |
(function () { | |
var lastPeerId = null; | |
var peer = null; // Own peer object | |
var peerId = null; | |
var conn = null; | |
var recvId = document.getElementById('receiver-id'); | |
var status = document.getElementById('status'); | |
var message = document.getElementById('message'); | |
var standbyBox = document.getElementById('standby'); | |
var goBox = document.getElementById('go'); | |
var fadeBox = document.getElementById('fade'); | |
var offBox = document.getElementById('off'); | |
var sendMessageBox = document.getElementById('sendMessageBox'); | |
var sendButton = document.getElementById('sendButton'); | |
var clearMsgsButton = document.getElementById('clearMsgsButton'); | |
/** | |
* Create the Peer object for our end of the connection. | |
* | |
* Sets up callbacks that handle any events related to our | |
* peer object. | |
*/ | |
function initialize() { | |
// Create own peer object with connection to shared PeerJS server | |
peer = new Peer(null, { | |
debug: 2, | |
}); | |
peer.on('open', function (id) { | |
// Workaround for peer.reconnect deleting previous id | |
if (peer.id === null) { | |
console.log('Received null id from peer open'); | |
peer.id = lastPeerId; | |
} else { | |
lastPeerId = peer.id; | |
} | |
console.log('ID: ' + peer.id); | |
recvId.innerHTML = 'ID: ' + peer.id; | |
status.innerHTML = 'Awaiting connection...'; | |
}); | |
peer.on('connection', function (c) { | |
// Allow only a single connection | |
if (conn && conn.open) { | |
c.on('open', function () { | |
c.send('Already connected to another client'); | |
setTimeout(function () { | |
c.close(); | |
}, 500); | |
}); | |
return; | |
} | |
conn = c; | |
console.log('Connected to: ' + conn.peer); | |
status.innerHTML = 'Connected'; | |
ready(); | |
}); | |
peer.on('disconnected', function () { | |
status.innerHTML = 'Connection lost. Please reconnect'; | |
console.log('Connection lost. Please reconnect'); | |
// Workaround for peer.reconnect deleting previous id | |
peer.id = lastPeerId; | |
peer._lastServerId = lastPeerId; | |
peer.reconnect(); | |
}); | |
peer.on('close', function () { | |
conn = null; | |
status.innerHTML = 'Connection destroyed. Please refresh'; | |
console.log('Connection destroyed'); | |
}); | |
peer.on('error', function (err) { | |
console.log(err); | |
alert('' + err); | |
}); | |
} | |
/** | |
* Triggered once a connection has been achieved. | |
* Defines callbacks to handle incoming data and connection events. | |
*/ | |
function ready() { | |
conn.on('data', function (data) { | |
console.log('Data recieved'); | |
var cueString = '<span class="cueMsg">Cue: </span>'; | |
switch (data) { | |
case 'Go': | |
go(); | |
addMessage(cueString + data); | |
break; | |
case 'Fade': | |
fade(); | |
addMessage(cueString + data); | |
break; | |
case 'Off': | |
off(); | |
addMessage(cueString + data); | |
break; | |
case 'Reset': | |
reset(); | |
addMessage(cueString + data); | |
break; | |
default: | |
addMessage('<span class="peerMsg">Peer: </span>' + data); | |
break; | |
} | |
}); | |
conn.on('close', function () { | |
status.innerHTML = 'Connection reset<br>Awaiting connection...'; | |
conn = null; | |
}); | |
} | |
function go() { | |
standbyBox.className = 'display-box hidden'; | |
goBox.className = 'display-box go'; | |
fadeBox.className = 'display-box hidden'; | |
offBox.className = 'display-box hidden'; | |
return; | |
} | |
function fade() { | |
standbyBox.className = 'display-box hidden'; | |
goBox.className = 'display-box hidden'; | |
fadeBox.className = 'display-box fade'; | |
offBox.className = 'display-box hidden'; | |
return; | |
} | |
function off() { | |
standbyBox.className = 'display-box hidden'; | |
goBox.className = 'display-box hidden'; | |
fadeBox.className = 'display-box hidden'; | |
offBox.className = 'display-box off'; | |
return; | |
} | |
function reset() { | |
standbyBox.className = 'display-box standby'; | |
goBox.className = 'display-box hidden'; | |
fadeBox.className = 'display-box hidden'; | |
offBox.className = 'display-box hidden'; | |
return; | |
} | |
function addMessage(msg) { | |
var now = new Date(); | |
var h = now.getHours(); | |
var m = addZero(now.getMinutes()); | |
var s = addZero(now.getSeconds()); | |
if (h > 12) h -= 12; | |
else if (h === 0) h = 12; | |
function addZero(t) { | |
if (t < 10) t = '0' + t; | |
return t; | |
} | |
message.innerHTML = | |
'<br><span class="msg-time">' + | |
h + | |
':' + | |
m + | |
':' + | |
s + | |
'</span> - ' + | |
msg + | |
message.innerHTML; | |
} | |
function clearMessages() { | |
message.innerHTML = ''; | |
addMessage('Msgs cleared'); | |
} | |
// Listen for enter in message box | |
sendMessageBox.addEventListener('keypress', function (e) { | |
var event = e || window.event; | |
var char = event.which || event.keyCode; | |
if (char == '13') sendButton.click(); | |
}); | |
// Send message | |
sendButton.addEventListener('click', function () { | |
if (conn && conn.open) { | |
var msg = sendMessageBox.value; | |
sendMessageBox.value = ''; | |
conn.send(msg); | |
console.log('Sent: ' + msg); | |
addMessage('<span class="selfMsg">Self: </span>' + msg); | |
} else { | |
console.log('Connection is closed'); | |
} | |
}); | |
// Clear messages box | |
clearMsgsButton.addEventListener('click', clearMessages); | |
initialize(); | |
})(); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width" /> | |
<title>Peer-to-Peer Cue System --- Sender</title> | |
<style> | |
body { | |
font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; | |
background-color: white; | |
min-width: 450px; | |
} | |
h1 { | |
font-size: 1.75em; | |
} | |
h2 { | |
text-align: center; | |
font-size: 4em; | |
} | |
td { | |
width: 50%; | |
} | |
input { | |
margin-bottom: 5px; | |
} | |
a:visited { | |
color: blue; | |
} | |
.display { | |
width: 100%; | |
min-height: 400px; | |
padding-bottom: 20px; | |
} | |
.control { | |
width: 100%; | |
padding-bottom: 20px; | |
} | |
.control-button { | |
width: 100%; | |
min-height: 50px; | |
} | |
.display-box { | |
border: 2px solid black; | |
} | |
.title { | |
vertical-align: top; | |
} | |
.standby { | |
background-color: red; | |
} | |
.go { | |
background-color: green; | |
} | |
.fade { | |
background-color: yellow; | |
} | |
.off { | |
background-color: gray; | |
} | |
.hidden { | |
visibility: hidden; | |
} | |
.no-display { | |
display: none; | |
} | |
.status { | |
height: 125px; | |
vertical-align: text-top; | |
font-weight: bold; | |
margin-bottom: 10px; | |
border-bottom: 2px solid black; | |
} | |
.message { | |
height: 125px; | |
max-height: 125px; | |
margin-bottom: 10px; | |
border-bottom: 2px solid black; | |
overflow: auto; | |
} | |
.msg-time { | |
color: blue; | |
} | |
.cueMsg { | |
color: orange; | |
} | |
.selfMsg { | |
color: green; | |
} | |
.peerMsg { | |
color: red; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Peer-to-Peer Cue System --- Sender</h1> | |
<table class="control"> | |
<tr> | |
<td class="title">Status:</td> | |
<td class="title">Messages:</td> | |
</tr> | |
<tr> | |
<td> | |
<span style="font-weight: bold">ID: </span> | |
<input type="text" id="receiver-id" title="Input the ID from receive.html" /> | |
<button id="connect-button">Connect</button> | |
</td> | |
<td> | |
<input type="text" id="sendMessageBox" placeholder="Enter a message..." autofocus="true" /> | |
<button type="button" id="sendButton">Send</button> | |
<button type="button" id="clearMsgsButton">Clear Msgs (Local)</button> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<div id="status" class="status"></div> | |
</td> | |
<td> | |
<div class="message" id="message"></div> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<button type="button" class="control-button" id="resetButton"> | |
Reset | |
</button> | |
</td> | |
<td> | |
<button type="button" class="control-button" id="goButton">Go</button> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<button type="button" class="control-button" id="fadeButton"> | |
Fade | |
</button> | |
</td> | |
<td> | |
<button type="button" class="control-button" id="offButton"> | |
Off | |
</button> | |
</td> | |
</tr> | |
</table> | |
<script src="https://unpkg.com/[email protected]/dist/peerjs.min.js"></script> | |
<script type="text/javascript"> | |
(function () { | |
var lastPeerId = null; | |
var peer = null; // own peer object | |
var conn = null; | |
var recvIdInput = document.getElementById('receiver-id'); | |
var status = document.getElementById('status'); | |
var message = document.getElementById('message'); | |
var goButton = document.getElementById('goButton'); | |
var resetButton = document.getElementById('resetButton'); | |
var fadeButton = document.getElementById('fadeButton'); | |
var offButton = document.getElementById('offButton'); | |
var sendMessageBox = document.getElementById('sendMessageBox'); | |
var sendButton = document.getElementById('sendButton'); | |
var clearMsgsButton = document.getElementById('clearMsgsButton'); | |
var connectButton = document.getElementById('connect-button'); | |
var cueString = '<span class="cueMsg">Cue: </span>'; | |
/** | |
* Create the Peer object for our end of the connection. | |
* | |
* Sets up callbacks that handle any events related to our | |
* peer object. | |
*/ | |
function initialize() { | |
// Create own peer object with connection to shared PeerJS server | |
peer = new Peer(null, { | |
debug: 2, | |
}); | |
peer.on('open', function (id) { | |
// Workaround for peer.reconnect deleting previous id | |
if (peer.id === null) { | |
console.log('Received null id from peer open'); | |
peer.id = lastPeerId; | |
} else { | |
lastPeerId = peer.id; | |
} | |
console.log('ID: ' + peer.id); | |
}); | |
peer.on('connection', function (c) { | |
// Disallow incoming connections | |
c.on('open', function () { | |
c.send('Sender does not accept incoming connections'); | |
setTimeout(function () { | |
c.close(); | |
}, 500); | |
}); | |
}); | |
peer.on('disconnected', function () { | |
status.innerHTML = 'Connection lost. Please reconnect'; | |
console.log('Connection lost. Please reconnect'); | |
// Workaround for peer.reconnect deleting previous id | |
peer.id = lastPeerId; | |
peer._lastServerId = lastPeerId; | |
peer.reconnect(); | |
}); | |
peer.on('close', function () { | |
conn = null; | |
status.innerHTML = 'Connection destroyed. Please refresh'; | |
console.log('Connection destroyed'); | |
}); | |
peer.on('error', function (err) { | |
console.log(err); | |
alert('' + err); | |
}); | |
} | |
/** | |
* Create the connection between the two Peers. | |
* | |
* Sets up callbacks that handle any events related to the | |
* connection and data received on it. | |
*/ | |
function join() { | |
// Close old connection | |
if (conn) { | |
conn.close(); | |
} | |
// Create connection to destination peer specified in the input field | |
conn = peer.connect(recvIdInput.value, { | |
reliable: true, | |
}); | |
conn.on('open', function () { | |
status.innerHTML = 'Connected to: ' + conn.peer; | |
console.log('Connected to: ' + conn.peer); | |
// Check URL params for comamnds that should be sent immediately | |
var command = getUrlParam('command'); | |
if (command) conn.send(command); | |
}); | |
// Handle incoming data (messages only since this is the signal sender) | |
conn.on('data', function (data) { | |
addMessage('<span class="peerMsg">Peer:</span> ' + data); | |
}); | |
conn.on('close', function () { | |
status.innerHTML = 'Connection closed'; | |
}); | |
} | |
/** | |
* Get first "GET style" parameter from href. | |
* This enables delivering an initial command upon page load. | |
* | |
* Would have been easier to use location.hash. | |
*/ | |
function getUrlParam(name) { | |
name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); | |
var regexS = '[\\?&]' + name + '=([^&#]*)'; | |
var regex = new RegExp(regexS); | |
var results = regex.exec(window.location.href); | |
if (results == null) return null; | |
else return results[1]; | |
} | |
/** | |
* Send a signal via the peer connection and add it to the log. | |
* This will only occur if the connection is still alive. | |
*/ | |
function signal(sigName) { | |
if (conn && conn.open) { | |
conn.send(sigName); | |
console.log(sigName + ' signal sent'); | |
addMessage(cueString + sigName); | |
} else { | |
console.log('Connection is closed'); | |
} | |
} | |
goButton.addEventListener('click', function () { | |
signal('Go'); | |
}); | |
resetButton.addEventListener('click', function () { | |
signal('Reset'); | |
}); | |
fadeButton.addEventListener('click', function () { | |
signal('Fade'); | |
}); | |
offButton.addEventListener('click', function () { | |
signal('Off'); | |
}); | |
function addMessage(msg) { | |
var now = new Date(); | |
var h = now.getHours(); | |
var m = addZero(now.getMinutes()); | |
var s = addZero(now.getSeconds()); | |
if (h > 12) h -= 12; | |
else if (h === 0) h = 12; | |
function addZero(t) { | |
if (t < 10) t = '0' + t; | |
return t; | |
} | |
message.innerHTML = | |
'<br><span class="msg-time">' + | |
h + | |
':' + | |
m + | |
':' + | |
s + | |
'</span> - ' + | |
msg + | |
message.innerHTML; | |
} | |
function clearMessages() { | |
message.innerHTML = ''; | |
addMessage('Msgs cleared'); | |
} | |
// Listen for enter in message box | |
sendMessageBox.addEventListener('keypress', function (e) { | |
var event = e || window.event; | |
var char = event.which || event.keyCode; | |
if (char == '13') sendButton.click(); | |
}); | |
// Send message | |
sendButton.addEventListener('click', function () { | |
if (conn && conn.open) { | |
var msg = sendMessageBox.value; | |
sendMessageBox.value = ''; | |
conn.send(msg); | |
console.log('Sent: ' + msg); | |
addMessage('<span class="selfMsg">Self: </span> ' + msg); | |
} else { | |
console.log('Connection is closed'); | |
} | |
}); | |
// Clear messages box | |
clearMsgsButton.addEventListener('click', clearMessages); | |
// Start peer connection on click | |
connectButton.addEventListener('click', join); | |
// Since all our callbacks are setup, start the process of obtaining an ID | |
initialize(); | |
})(); | |
</script> | |
<div hidden> | |
# Peer-to-Peer Cue System # | |
Cue system for simple two-way communication and visual signaling using a WebRTC peer-to-peer connection. | |
This was initially designed for signaling on-stage actors during a theater performance. | |
Demo: https://jmcker.github.io/Peer-to-Peer-Cue-System | |
[PeerJS examples](https://peerjs.com/examples.html) | |
### Setup ### | |
1. Open receive.html on the receiving device. | |
2. Open send.html on the sending device. | |
3. Copy the ID from the receiving device to the sending device's ID field. | |
4. Press *Connect*. | |
4. Both should indicate a successful connection in the *Status* box. | |
### Features ### | |
The receiver has access to large indicators for standby, go, fade, and stop signals. | |
The sender has access to buttons that send the standby, go, fade, and stop signals, triggering the receiver's | |
indicators. | |
Both have access to a two-way messenger for additional communication. | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment