Allow Multiple P2P Connections at once
parent
1944831138
commit
c10efb12f4
|
@ -8,6 +8,9 @@ let config = workerData.config
|
|||
let lang = workerData.lang
|
||||
let sslInfo = config.ssl || {}
|
||||
let remoteConnectionPort = config.easyRemotePort || (sslInfo && sslInfo.port && (sslInfo.enabled !== false) ? sslInfo.port : config.port || 8080)
|
||||
const multipleSelected = config.p2pHostMultiSelected instanceof Array && config.p2pHostMultiSelected.length > 0;
|
||||
const p2pApiKey = config.p2pApiKey;
|
||||
const p2pServerList = config.p2pServerList;
|
||||
const net = require("net")
|
||||
const bson = require('bson')
|
||||
const WebSocket = require('cws')
|
||||
|
@ -36,11 +39,11 @@ parentPort.on('message',(data) => {
|
|||
break;
|
||||
}
|
||||
})
|
||||
var socketCheckTimer = null
|
||||
var heartbeatTimer = null
|
||||
var heartBeatCheckTimout = null
|
||||
var onClosedTimeout = null
|
||||
let stayDisconnected = false
|
||||
var socketCheckTimer = {}
|
||||
var heartbeatTimer = {}
|
||||
var heartBeatCheckTimout = {}
|
||||
var onClosedTimeout = {}
|
||||
let stayDisconnected = {}
|
||||
const requestConnections = {}
|
||||
const requestConnectionsData = {}
|
||||
function getRequestConnection(requestId){
|
||||
|
@ -48,29 +51,28 @@ function getRequestConnection(requestId){
|
|||
write: () => {}
|
||||
}
|
||||
}
|
||||
function clearAllTimeouts(){
|
||||
clearInterval(heartbeatTimer)
|
||||
clearTimeout(heartBeatCheckTimout)
|
||||
clearTimeout(onClosedTimeout)
|
||||
function clearAllTimeouts(p2pServerAddress){
|
||||
clearInterval(heartbeatTimer[p2pServerAddress])
|
||||
clearTimeout(heartBeatCheckTimout[p2pServerAddress])
|
||||
clearTimeout(onClosedTimeout[p2pServerAddress])
|
||||
}
|
||||
function startConnection(p2pServerAddress,subscriptionId){
|
||||
let tunnelToP2P
|
||||
stayDisconnected = false
|
||||
stayDisconnected[p2pServerAddress] = false
|
||||
const allMessageHandlers = []
|
||||
async function startWebsocketConnection(key,callback){
|
||||
s.debugLog(`startWebsocketConnection EXECUTE`,new Error())
|
||||
console.log('P2P : Connecting to Konekta P2P Server...')
|
||||
function createWebsocketConnection(){
|
||||
clearAllTimeouts()
|
||||
return new Promise((resolve,reject) => {
|
||||
try{
|
||||
stayDisconnected = true
|
||||
stayDisconnected[p2pServerAddress] = true
|
||||
if(tunnelToP2P)tunnelToP2P.close()
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
}
|
||||
tunnelToP2P = new WebSocket(p2pServerAddress);
|
||||
stayDisconnected = false;
|
||||
stayDisconnected[p2pServerAddress] = false;
|
||||
tunnelToP2P.on('open', function(){
|
||||
resolve(tunnelToP2P)
|
||||
})
|
||||
|
@ -81,7 +83,7 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
})
|
||||
tunnelToP2P.on('close', () => {
|
||||
console.log(`P2P Connection Closed!`)
|
||||
clearAllTimeouts()
|
||||
clearAllTimeouts(p2pServerAddress)
|
||||
// onClosedTimeout = setTimeout(() => {
|
||||
// disconnectedConnection();
|
||||
// },5000)
|
||||
|
@ -95,8 +97,8 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
})
|
||||
}
|
||||
|
||||
clearInterval(socketCheckTimer)
|
||||
socketCheckTimer = setInterval(() => {
|
||||
clearInterval(socketCheckTimer[p2pServerAddress])
|
||||
socketCheckTimer[p2pServerAddress] = setInterval(() => {
|
||||
// s.debugLog('Tunnel Ready State :',tunnelToP2P.readyState)
|
||||
if(tunnelToP2P.readyState !== 1){
|
||||
s.debugLog('Tunnel NOT Ready! Reconnecting...')
|
||||
|
@ -106,10 +108,10 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
})
|
||||
}
|
||||
function disconnectedConnection(code,reason){
|
||||
s.debugLog('stayDisconnected',stayDisconnected)
|
||||
s.debugLog('stayDisconnected',stayDisconnected[p2pServerAddress])
|
||||
clearAllTimeouts()
|
||||
s.debugLog('DISCONNECTED!')
|
||||
if(stayDisconnected)return;
|
||||
if(stayDisconnected[p2pServerAddress])return;
|
||||
s.debugLog('RESTARTING!')
|
||||
setTimeout(() => {
|
||||
if(tunnelToP2P && tunnelToP2P.readyState !== 1)startWebsocketConnection()
|
||||
|
@ -122,8 +124,8 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
subscriptionId: subscriptionId,
|
||||
restrictedTo: config.p2pRestrictedTo || [],
|
||||
})
|
||||
clearInterval(heartbeatTimer)
|
||||
heartbeatTimer = setInterval(() => {
|
||||
clearInterval(heartbeatTimer[p2pServerAddress])
|
||||
heartbeatTimer[p2pServerAddress] = setInterval(() => {
|
||||
sendDataToTunnel({
|
||||
f: 'ping',
|
||||
})
|
||||
|
@ -158,7 +160,7 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
// remotesocket.off('close')
|
||||
// requestConnections[requestId].end()
|
||||
// }
|
||||
const responseTunnel = await getResponseTunnel(requestId)
|
||||
const responseTunnel = await getResponseTunnel(requestId, p2pServerAddress)
|
||||
let remotesocket = new net.Socket();
|
||||
remotesocket.on('ready',() => {
|
||||
remotesocket.write(initData.buffer)
|
||||
|
@ -196,8 +198,8 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
}
|
||||
}
|
||||
function refreshHeartBeatCheck(){
|
||||
clearTimeout(heartBeatCheckTimout)
|
||||
heartBeatCheckTimout = setTimeout(() => {
|
||||
clearTimeout(heartBeatCheckTimout[p2pServerAddress])
|
||||
heartBeatCheckTimout[p2pServerAddress] = setTimeout(() => {
|
||||
startWebsocketConnection()
|
||||
},1000 * 10 * 1.5)
|
||||
}
|
||||
|
@ -304,15 +306,16 @@ function startConnection(p2pServerAddress,subscriptionId){
|
|||
onIncomingMessage('disconnect',function(data,requestId){
|
||||
console.log(`FAILED LICENSE CHECK ON P2P`)
|
||||
const retryLater = data && data.retryLater;
|
||||
stayDisconnected = !retryLater
|
||||
stayDisconnected[p2pServerAddress] = !retryLater
|
||||
if(retryLater)console.log(`Retrying P2P Later...`)
|
||||
})
|
||||
return tunnelToP2P;
|
||||
}
|
||||
const responseTunnels = {}
|
||||
async function getResponseTunnel(originalRequestId){
|
||||
return responseTunnels[originalRequestId] || await createResponseTunnel(originalRequestId)
|
||||
async function getResponseTunnel(originalRequestId, p2pServerAddress){
|
||||
return responseTunnels[originalRequestId] || await createResponseTunnel(originalRequestId, p2pServerAddress)
|
||||
}
|
||||
function createResponseTunnel(originalRequestId){
|
||||
function createResponseTunnel(originalRequestId, p2pServerAddress){
|
||||
const responseTunnelMessageHandlers = []
|
||||
function onMessage(key,callback){
|
||||
responseTunnelMessageHandlers.push({
|
||||
|
@ -321,7 +324,7 @@ function createResponseTunnel(originalRequestId){
|
|||
})
|
||||
}
|
||||
return new Promise((resolve,reject) => {
|
||||
const responseTunnel = new WebSocket(config.selectedHost);
|
||||
const responseTunnel = new WebSocket(p2pServerAddress);
|
||||
function sendToResponseTunnel(data){
|
||||
responseTunnel.send(
|
||||
bson.serialize(data)
|
||||
|
@ -374,10 +377,19 @@ function closeResponseTunnel(originalRequestId){
|
|||
s.debugLog('closeResponseTunnel',err)
|
||||
}
|
||||
}
|
||||
function initialize(){
|
||||
const selectedP2PServerId = config.p2pServerList[config.p2pHostSelected] ? config.p2pHostSelected : Object.keys(config.p2pServerList)[0]
|
||||
const p2pServerDetails = config.p2pServerList[selectedP2PServerId]
|
||||
function initialize(p2pHostSelected){
|
||||
const selectedP2PServerId = p2pServerList[p2pHostSelected] ? p2pHostSelected : Object.keys(p2pServerList)[0]
|
||||
const p2pServerDetails = p2pServerList[selectedP2PServerId]
|
||||
const selectedHost = `${p2pServerDetails.secure ? `wss` : 'ws'}://` + p2pServerDetails.host + ':' + p2pServerDetails.p2pPort
|
||||
config.selectedHost = selectedHost
|
||||
startConnection(selectedHost,config.p2pApiKey)
|
||||
startConnection(selectedHost,p2pApiKey)
|
||||
}
|
||||
if(multipleSelected){
|
||||
for(aSelection of config.p2pHostMultiSelected){
|
||||
clearAllTimeouts(aSelection)
|
||||
initialize(aSelection)
|
||||
}
|
||||
}else{
|
||||
const singleSelection = config.p2pHostSelected;
|
||||
clearAllTimeouts(singleSelection)
|
||||
initialize(singleSelection)
|
||||
}
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
#easyRemoteAccess .card.active .fa {
|
||||
color: #6ee068;
|
||||
}
|
||||
#easyRemoteAccess .card .remote-dashboard-link {
|
||||
display: none!important;
|
||||
}
|
||||
#easyRemoteAccess .card.active .remote-dashboard-link {
|
||||
display: block!important;
|
||||
}
|
||||
#easyRemoteAccess .card .selected-badge {
|
||||
display: none;
|
||||
color: #fff!important;
|
||||
|
@ -56,3 +62,7 @@
|
|||
#p2pServerList .card .d-flex.flex-row:nth-of-type(odd) {
|
||||
background: rgba(0,0,0,0.1)
|
||||
}
|
||||
|
||||
#easyRemoteAccess .active .activate-remote-selection .fa-check:before {
|
||||
content: "\f00d"!important;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ $(document).ready(function(){
|
|||
var remoteDashboardLinkButton = easyRemoteAccessTab.find('.remote-dashboard-link')
|
||||
var loadingRegistration = false
|
||||
var statusConnections = {}
|
||||
var currentlyRegisteredP2PServer = currentlySelectedP2PServerId ? currentlySelectedP2PServerId + '' : undefined
|
||||
function copyToClipboard(str) {
|
||||
const el = document.createElement('textarea');
|
||||
el.value = str;
|
||||
|
@ -72,37 +71,11 @@ $(document).ready(function(){
|
|||
loadingRegistration = false
|
||||
easyRemoteAccessTab.find('.remote-dashboard-link').html(`<i class="fa fa-external-link"></i> ` + lang['Open Remote Dashboard'])
|
||||
easyRemoteAccessTab.find('.remote-dashboard-link-copy').html(`<i class="fa fa-copy"></i> ` + lang['Copy Remote Link'])
|
||||
displayCurrentlySelectedInternally()
|
||||
}
|
||||
function displayCurrentlySelectedInternally(){
|
||||
var selectedServer = p2pServerList[currentlyRegisteredP2PServer]
|
||||
if(selectedServer){
|
||||
var key = selectedServer.key
|
||||
var cardEl = easyRemoteAccessTab.find(`[drawn-id="${key}"]`)
|
||||
easyRemoteAccessTab.find(`[drawn-id].selected`).removeClass('selected')
|
||||
cardEl.addClass('selected')
|
||||
setCurrentRemoteLink()
|
||||
}
|
||||
}
|
||||
function makeHostLink(selectedServer,apiKey){
|
||||
var href = `https://${selectedServer.host}:${selectedServer.webPort == 80 ? 443 : selectedServer.webPort}/s/${apiKey}/`
|
||||
return href
|
||||
}
|
||||
function setCurrentRemoteLink(){
|
||||
var apiKey = easyRemoteAccessForm.find('[name="p2pApiKey"]').val()
|
||||
var selectedServer = p2pServerList[currentlyRegisteredP2PServer]
|
||||
console.log(selectedServer,currentlySelectedP2PServerId,p2pServerList)
|
||||
if(selectedServer && selectedServer.host){
|
||||
var href = makeHostLink(selectedServer,apiKey)
|
||||
remoteDashboardLinkButton.attr('href',href)
|
||||
}else{
|
||||
new PNotify({
|
||||
type: 'warning',
|
||||
title: lang['P2P Server Not Selected'],
|
||||
text: lang.p2pServerNotSelectedText,
|
||||
})
|
||||
}
|
||||
}
|
||||
function beginAllStatusConnections(){
|
||||
$.each(p2pServerList,function(key,server){
|
||||
server.key = key
|
||||
|
@ -127,6 +100,14 @@ $(document).ready(function(){
|
|||
toggleAffected.hide()
|
||||
}
|
||||
}
|
||||
function getSelectedServers(){
|
||||
var theArray = [];
|
||||
$(`[drawn-id].active`).each(function(){
|
||||
var theKey = $(this).attr('drawn-id')
|
||||
theArray.push(theKey)
|
||||
})
|
||||
return theArray
|
||||
}
|
||||
p2pEnabledSwitch.change(setVisibilityForList)
|
||||
easyRemoteAccessTab.find('.submit').click(function(){
|
||||
easyRemoteAccessForm.submit()
|
||||
|
@ -135,39 +116,51 @@ $(document).ready(function(){
|
|||
e.preventDefault()
|
||||
var formValues = $(this).serializeObject()
|
||||
disableForm()
|
||||
formValues.p2pHostSelected = currentlySelectedP2PServerId
|
||||
// formValues.p2pHostSelected = currentlySelectedP2PServerId
|
||||
formValues.p2pHostMultiSelected = getSelectedServers()
|
||||
console.log(formValues)
|
||||
$.post(superApiPrefix + $user.sessionKey + '/p2p/save',{
|
||||
data: JSON.stringify(formValues)
|
||||
},function(data){
|
||||
console.log(data)
|
||||
if(data.ok){
|
||||
currentlyRegisteredP2PServer = currentlySelectedP2PServerId + ''
|
||||
new PNotify({
|
||||
type: 'success',
|
||||
title: lang['P2P Settings Applied'],
|
||||
text: lang.p2pSettingsText1,
|
||||
})
|
||||
setCurrentRemoteLink()
|
||||
setTimeout(enableForm,5000)
|
||||
}
|
||||
})
|
||||
return false
|
||||
})
|
||||
easyRemoteAccessForm.on('click','[drawn-id]',function(){
|
||||
easyRemoteAccessTab.on('click','.activate-remote-selection',function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this)
|
||||
var p2pServerId = el.attr('drawn-id')
|
||||
easyRemoteAccessForm.find('[drawn-id]').removeClass('active')
|
||||
el.addClass('active')
|
||||
currentlySelectedP2PServerId = p2pServerId
|
||||
var parent = el.parents('[drawn-id]')
|
||||
var drawnId = parent.attr('drawn-id')
|
||||
var alreadyActive = parent.hasClass('active')
|
||||
var selectedServer = p2pServerList[drawnId]
|
||||
var isWss = selectedServer.p2pPort == 443
|
||||
console.log(selectedServer)
|
||||
if(alreadyActive){
|
||||
parent.removeClass('active')
|
||||
}else{
|
||||
parent.addClass('active')
|
||||
const drawnIdToDisable = isWss ? drawnId.replace('-ssl','') : `${drawnId}-ssl`
|
||||
console.log(drawnIdToDisable)
|
||||
easyRemoteAccessTab.find(`[drawn-id="${drawnIdToDisable}"]`).removeClass('active')
|
||||
}
|
||||
return false;
|
||||
})
|
||||
easyRemoteAccessTab.on('click','.remote-dashboard-link-copy',function(e){
|
||||
e.preventDefault()
|
||||
if(!loadingRegistration){
|
||||
var parent = $(this).parents('[drawn-id]')
|
||||
var drawnId = parent.attr('drawn-id')
|
||||
var apiKey = easyRemoteAccessForm.find('[name="p2pApiKey"]').val()
|
||||
var selectedServer = p2pServerList[currentlyRegisteredP2PServer]
|
||||
console.log(selectedServer,currentlySelectedP2PServerId,p2pServerList)
|
||||
if(selectedServer && selectedServer.host){
|
||||
var selectedServer = p2pServerList[drawnId]
|
||||
if(parent.hasClass('active') && selectedServer && selectedServer.host){
|
||||
var href = makeHostLink(selectedServer,apiKey)
|
||||
copyToClipboard(href)
|
||||
new PNotify({
|
||||
|
@ -183,8 +176,24 @@ $(document).ready(function(){
|
|||
})
|
||||
}
|
||||
}
|
||||
e.stopPropagation()
|
||||
return false;
|
||||
})
|
||||
easyRemoteAccessTab.on('click','.remote-dashboard-link',function(e){
|
||||
e.preventDefault()
|
||||
if(!loadingRegistration){
|
||||
var parent = $(this).parents('[drawn-id]')
|
||||
var drawnId = parent.attr('drawn-id')
|
||||
var apiKey = easyRemoteAccessForm.find('[name="p2pApiKey"]').val()
|
||||
var selectedServer = p2pServerList[drawnId]
|
||||
console.log(selectedServer,parent.hasClass('active'),parent.length)
|
||||
if(parent.hasClass('active') && selectedServer && selectedServer.host){
|
||||
var href = makeHostLink(selectedServer,apiKey)
|
||||
window.open(href, '_blank').focus();
|
||||
}
|
||||
}
|
||||
e.stopPropagation()
|
||||
return false;
|
||||
})
|
||||
setVisibilityForList()
|
||||
displayCurrentlySelectedInternally()
|
||||
})
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<% const p2pServerList = config.p2pServerList || {}
|
||||
const selectedServer = p2pServerList[config.p2pHostSelected]
|
||||
<%
|
||||
const p2pServerList = config.p2pServerList || {}
|
||||
const selectedServers = config.p2pHostMultiSelected
|
||||
const multipleSelected = selectedServers instanceof Array && selectedServers.length > 0;
|
||||
%>
|
||||
<style>
|
||||
.epic-text-filter {
|
||||
|
@ -19,8 +21,9 @@
|
|||
</style>
|
||||
<script>
|
||||
window.p2pServerList = <%- JSON.stringify(p2pServerList) %>
|
||||
window.multipleSelected = <%- multipleSelected %>
|
||||
window.selectedServers = <%- JSON.stringify(selectedServers) %>
|
||||
window.useBetterP2P = <%- !!config.useBetterP2P %>
|
||||
window.currentlySelectedP2PServerId = `<%- config.p2pHostSelected %>`
|
||||
</script>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>assets/css/super.easyRemoteAccess.css">
|
||||
<form>
|
||||
|
@ -40,12 +43,6 @@
|
|||
<div class="form-group p2p-toggle-affected">
|
||||
<input placeholder="<%-lang['P2P API Key']%>" class="form-control btn btn-dark text-left text-white" type="text" name="p2pApiKey" value="<%- config.p2pApiKey %>">
|
||||
</div>
|
||||
<div class="form-group p2p-toggle-affected">
|
||||
<div class="btn-group d-flex flex-row">
|
||||
<a target="_blank" href="#" class="flex-grow-1 btn btn-default remote-dashboard-link-copy"><i class="fa fa-copy"></i> <%- lang['Copy Remote Link'] %></a>
|
||||
<a target="_blank" href="#" class="flex-grow-1 btn btn-info remote-dashboard-link" target="_blank"><i class="fa fa-external-link"></i> <%- lang['Open Remote Dashboard'] %></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group d-flex flex-row">
|
||||
<a href="#" class="submit flex-grow-1 btn btn-success"><i class="fa fa-check"></i> <%- lang.Save %></a>
|
||||
</div>
|
||||
|
@ -72,7 +69,7 @@
|
|||
if(!config.useBetterP2P && details.v2)return;
|
||||
%>
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-dark cursor-pointer text-white mb-4 <% if(config.p2pHostSelected === key){ %>active<% } %>" drawn-id="<%- key %>">
|
||||
<div class="card bg-dark cursor-pointer text-white mb-4 <% if((!multipleSelected && config.p2pHostSelected === key) || multipleSelected && selectedServers.indexOf(key) > -1){ %>active<% } %>" drawn-id="<%- key %>">
|
||||
<div class="card-header" style="min-height:auto">
|
||||
<span class="badge badge-sm badge-danger pull-right selected-badge"><%- lang.Selected %></span>
|
||||
<span class="badge badge-sm badge-info name-badge"><%- details.name.toUpperCase() %></span>
|
||||
|
@ -107,7 +104,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="min-height:auto">
|
||||
<a class="btn badge badge-sm badge-warning geo-badge" target="_blank" href="<%- `https://www.google.ca/maps/@${details.location.lat},${details.location.lon},15z` %>"><i class="fa fa-map-marker"></i> <%- details.location.lat %>, <%- details.location.lon %></a>
|
||||
<div>
|
||||
<a target="_blank" href="#" class="d-block btn btn-default activate-remote-selection"><i class="fa fa-check"></i> <%- lang['Activate'] %></a>
|
||||
<a target="_blank" href="#" class="d-block btn btn-default remote-dashboard-link-copy"><i class="fa fa-copy"></i> <%- lang['Copy Remote Link'] %></a>
|
||||
<a target="_blank" href="#" class="d-block btn btn-info remote-dashboard-link" target="_blank"><i class="fa fa-external-link"></i> <%- lang['Open Remote Dashboard'] %></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -115,7 +116,6 @@
|
|||
</div>
|
||||
<div class="form-group p2p-toggle-affected">
|
||||
<div class="btn-group d-flex flex-row">
|
||||
<a target="_blank" href="#" class="flex-grow-1 btn btn-info remote-dashboard-link" target="_blank"><i class="fa fa-external-link"></i> <%- lang['Open Remote Dashboard'] %></a>
|
||||
<a href="#" class="submit flex-grow-1 btn btn-success"><i class="fa fa-check"></i> <%- lang.Save %></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue