Client prototype, signaling server & PWA client
This commit is contained in:
21
server/.gitignore
vendored
Normal file
21
server/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
3
server/config.json
Normal file
3
server/config.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"port" : 8080
|
||||
}
|
||||
602
server/package-lock.json
generated
Normal file
602
server/package-lock.json
generated
Normal file
@@ -0,0 +1,602 @@
|
||||
{
|
||||
"name": "lilstreamy-server",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz",
|
||||
"integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"circular-json": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz",
|
||||
"integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"requires": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
}
|
||||
},
|
||||
"crc": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
|
||||
"integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
|
||||
"requires": {
|
||||
"buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"date-format": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
|
||||
"integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.12.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz",
|
||||
"integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"log4js": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz",
|
||||
"integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==",
|
||||
"requires": {
|
||||
"circular-json": "^0.5.5",
|
||||
"date-format": "^1.2.0",
|
||||
"debug": "^3.1.0",
|
||||
"rfdc": "^1.1.2",
|
||||
"streamroller": "0.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
|
||||
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.26",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
|
||||
"integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.43.0"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"node-turn": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/node-turn/-/node-turn-0.0.4.tgz",
|
||||
"integrity": "sha512-ZmMbEt9146syRhBqrpgOTTdI5xn5seXpB6+/hkRLQV86ZHWuvF3TNHfN3TTFs3pf/ceY9rbdBs+OnaFQqqGU7g==",
|
||||
"requires": {
|
||||
"crc": "^3.8.0",
|
||||
"js-yaml": "~3.12.0",
|
||||
"log4js": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"rfdc": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz",
|
||||
"integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug=="
|
||||
},
|
||||
"rtcpeerconnection-shim": {
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
|
||||
"integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
|
||||
"requires": {
|
||||
"sdp": "^2.6.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sdp": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
|
||||
"integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"streamroller": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz",
|
||||
"integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==",
|
||||
"requires": {
|
||||
"date-format": "^1.2.0",
|
||||
"debug": "^3.1.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"readable-stream": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"webrtc-adapter": {
|
||||
"version": "7.5.1",
|
||||
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.5.1.tgz",
|
||||
"integrity": "sha512-R5LkIR/APjODkstSXFOztOmINXQ0nqIGfUoKTtCzjyiDXHNgwhkqZ9vi8UzGyjfUBibuZ0ZzVyV10qtuLGW3CQ==",
|
||||
"requires": {
|
||||
"rtcpeerconnection-shim": "^1.2.15",
|
||||
"sdp": "^2.12.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
19
server/package.json
Normal file
19
server/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "lilstreamy-server",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple webRTC server",
|
||||
"main": "src/server.js",
|
||||
"scripts": {
|
||||
"start": "node src/server.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"node-turn": "0.0.4",
|
||||
"webrtc-adapter": "^7.5.1",
|
||||
"ws": "^7.2.3"
|
||||
}
|
||||
}
|
||||
18
server/src/server.js
Normal file
18
server/src/server.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const express = require('express');
|
||||
const bodyParser = require("body-parser");
|
||||
const signal = require("./signal3");
|
||||
const cors = require("cors");
|
||||
const config = require("../config.json");
|
||||
|
||||
const app = express()
|
||||
const {port} = config
|
||||
|
||||
app.use(cors())
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
app.use(bodyParser.json())
|
||||
|
||||
app.use(express.static("../clientV"))
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Launching Lil'Streamy on ${port}`)
|
||||
})
|
||||
154
server/src/signal.js
Normal file
154
server/src/signal.js
Normal file
@@ -0,0 +1,154 @@
|
||||
const WebSocketServer = require('ws').Server;
|
||||
|
||||
var wss = new WebSocketServer({port: 9090});
|
||||
|
||||
var users = {};
|
||||
|
||||
wss.on('connection', function(connection) {
|
||||
|
||||
console.log("User connected");
|
||||
|
||||
//when server gets a message from a connected user
|
||||
connection.on('message', (message) => onMessage(connection, message));
|
||||
|
||||
//when user exits, for example closes a browser window
|
||||
//this may help if we are still in "offer","answer" or "candidate" state
|
||||
connection.on("close", () => onClose(connection));
|
||||
});
|
||||
|
||||
function sendTo(connection, message) {
|
||||
connection.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
function onClose(connection) {
|
||||
if(connection.name) {
|
||||
delete users[connection.name];
|
||||
|
||||
if(connection.otherName) {
|
||||
console.log("Disconnecting from ", connection.otherName);
|
||||
var conn = users[connection.otherName];
|
||||
conn.otherName = null;
|
||||
|
||||
if(conn != null) {
|
||||
sendTo(conn, {
|
||||
type: "leave"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMessage(connection, message) {
|
||||
var data;
|
||||
|
||||
//accepting only JSON messages
|
||||
try {
|
||||
data = JSON.parse(message);
|
||||
} catch (e) {
|
||||
console.log("Invalid JSON");
|
||||
data = {};
|
||||
}
|
||||
|
||||
//switching type of the user message
|
||||
switch (data.type) {
|
||||
//when a user tries to login
|
||||
case "login":
|
||||
console.log("User logged", data.name);
|
||||
|
||||
//if anyone is logged in with this username then refuse
|
||||
if(users[data.name]) {
|
||||
sendTo(connection, {
|
||||
type: "login",
|
||||
success: false
|
||||
});
|
||||
} else {
|
||||
//save user connection on the server
|
||||
users[data.target] = connection;
|
||||
connection.name = data.target;
|
||||
|
||||
sendTo(connection, {
|
||||
type: "login",
|
||||
success: true
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "offer":
|
||||
//for ex. UserA wants to call UserB
|
||||
console.log("Sending offer to: ", data.target);
|
||||
|
||||
//if UserB exists then send him offer details
|
||||
var conn = users[data.target];
|
||||
|
||||
if(conn != null) {
|
||||
//setting that UserA connected with UserB
|
||||
connection.otherName = data.target;
|
||||
|
||||
sendTo(conn, {
|
||||
type: "offer",
|
||||
offer: data.offer,
|
||||
name: connection.target
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "answer":
|
||||
console.log("Sending answer to: ", data.target);
|
||||
//for ex. UserB answers UserA
|
||||
var conn = users[data.target];
|
||||
|
||||
if(conn != null) {
|
||||
connection.otherName = data.target;
|
||||
sendTo(conn, {
|
||||
type: "answer",
|
||||
answer: data.answer
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "candidate":
|
||||
console.log("Sending candidate to:",data.target);
|
||||
var conn = users[data.name];
|
||||
|
||||
if(conn != null) {
|
||||
sendTo(conn, {
|
||||
type: "candidate",
|
||||
candidate: data.candidate
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "leave":
|
||||
console.log("Disconnecting from", data.target);
|
||||
var conn = users[data.target];
|
||||
conn.otherName = null;
|
||||
|
||||
//notify the other user so he can disconnect his peer connection
|
||||
if(conn != null) {
|
||||
sendTo(conn, {
|
||||
type: "leave"
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "video-offer":
|
||||
console.log("Send video offer to", data.target);
|
||||
var conn = users[data.name];
|
||||
|
||||
if(conn != null) {
|
||||
connection.otherName = data.target;
|
||||
sendTo(conn, {
|
||||
type: "video-offer",
|
||||
answer: data.answer
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sendTo(connection, {
|
||||
type: "error",
|
||||
message: "Command not found: " + data.type
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
330
server/src/signal2.js
Normal file
330
server/src/signal2.js
Normal file
@@ -0,0 +1,330 @@
|
||||
"use strict";
|
||||
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var fs = require('fs');
|
||||
var WebSocketServer = require('ws').Server;
|
||||
|
||||
// Pathnames of the SSL key and certificate files to use for
|
||||
// HTTPS connections.
|
||||
|
||||
const keyFilePath = "/etc/pki/tls/private/mdn-samples.mozilla.org.key";
|
||||
const certFilePath = "/etc/pki/tls/certs/mdn-samples.mozilla.org.crt";
|
||||
|
||||
// Used for managing the text chat user list.
|
||||
|
||||
var connectionArray = [];
|
||||
var nextID = Date.now();
|
||||
var appendToMakeUnique = 1;
|
||||
|
||||
// Output logging information to console
|
||||
|
||||
function log(text) {
|
||||
var time = new Date();
|
||||
|
||||
console.log("[" + time.toLocaleTimeString() + "] " + text);
|
||||
}
|
||||
|
||||
// If you want to implement support for blocking specific origins, this is
|
||||
// where you do it. Just return false to refuse WebSocket connections given
|
||||
// the specified origin.
|
||||
function originIsAllowed(origin) {
|
||||
return true; // We will accept all connections
|
||||
}
|
||||
|
||||
// Scans the list of users and see if the specified name is unique. If it is,
|
||||
// return true. Otherwise, returns false. We want all users to have unique
|
||||
// names.
|
||||
function isUsernameUnique(name) {
|
||||
var isUnique = true;
|
||||
var i;
|
||||
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
if (connectionArray[i].username === name) {
|
||||
isUnique = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isUnique;
|
||||
}
|
||||
|
||||
// Sends a message (which is already stringified JSON) to a single
|
||||
// user, given their username. We use this for the WebRTC signaling,
|
||||
// and we could use it for private text messaging.
|
||||
function sendToOneUser(target, msgString) {
|
||||
var isUnique = true;
|
||||
var i;
|
||||
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
if (connectionArray[i].username === target) {
|
||||
connectionArray[i].sendUTF(msgString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scan the list of connections and return the one for the specified
|
||||
// clientID. Each login gets an ID that doesn't change during the session,
|
||||
// so it can be tracked across username changes.
|
||||
function getConnectionForID(id) {
|
||||
var connect = null;
|
||||
var i;
|
||||
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
if (connectionArray[i].clientID === id) {
|
||||
connect = connectionArray[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return connect;
|
||||
}
|
||||
|
||||
// Builds a message object of type "userlist" which contains the names of
|
||||
// all connected users. Used to ramp up newly logged-in users and,
|
||||
// inefficiently, to handle name change notifications.
|
||||
function makeUserListMessage() {
|
||||
var userListMsg = {
|
||||
type: "userlist",
|
||||
users: []
|
||||
};
|
||||
var i;
|
||||
|
||||
// Add the users to the list
|
||||
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
userListMsg.users.push(connectionArray[i].username);
|
||||
}
|
||||
|
||||
return userListMsg;
|
||||
}
|
||||
|
||||
// Sends a "userlist" message to all chat members. This is a cheesy way
|
||||
// to ensure that every join/drop is reflected everywhere. It would be more
|
||||
// efficient to send simple join/drop messages to each user, but this is
|
||||
// good enough for this simple example.
|
||||
function sendUserListToAll() {
|
||||
var userListMsg = makeUserListMessage();
|
||||
var userListMsgStr = JSON.stringify(userListMsg);
|
||||
var i;
|
||||
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
connectionArray[i].sendUTF(userListMsgStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Try to load the key and certificate files for SSL so we can
|
||||
// do HTTPS (required for non-local WebRTC).
|
||||
|
||||
var httpsOptions = {
|
||||
key: null,
|
||||
cert: null
|
||||
};
|
||||
|
||||
try {
|
||||
httpsOptions.key = fs.readFileSync(keyFilePath);
|
||||
try {
|
||||
httpsOptions.cert = fs.readFileSync(certFilePath);
|
||||
} catch(err) {
|
||||
httpsOptions.key = null;
|
||||
httpsOptions.cert = null;
|
||||
}
|
||||
} catch(err) {
|
||||
httpsOptions.key = null;
|
||||
httpsOptions.cert = null;
|
||||
}
|
||||
|
||||
// If we were able to get the key and certificate files, try to
|
||||
// start up an HTTPS server.
|
||||
|
||||
var webServer = null;
|
||||
|
||||
try {
|
||||
if (httpsOptions.key && httpsOptions.cert) {
|
||||
webServer = https.createServer(httpsOptions, handleWebRequest);
|
||||
}
|
||||
} catch(err) {
|
||||
webServer = null;
|
||||
}
|
||||
|
||||
if (!webServer) {
|
||||
try {
|
||||
webServer = http.createServer({}, handleWebRequest);
|
||||
} catch(err) {
|
||||
webServer = null;
|
||||
log(`Error attempting to create HTTP(s) server: ${err.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Our HTTPS server does nothing but service WebSocket
|
||||
// connections, so every request just returns 404. Real Web
|
||||
// requests are handled by the main server on the box. If you
|
||||
// want to, you can return real HTML here and serve Web content.
|
||||
|
||||
function handleWebRequest(request, response) {
|
||||
log ("Received request for " + request.url);
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
}
|
||||
|
||||
// Spin up the HTTPS server on the port assigned to this sample.
|
||||
// This will be turned into a WebSocket port very shortly.
|
||||
|
||||
webServer.listen(6503, function() {
|
||||
log("Server is listening on port 6503");
|
||||
});
|
||||
|
||||
// Create the WebSocket server by converting the HTTPS server into one.
|
||||
|
||||
var wsServer = new WebSocketServer({
|
||||
httpServer: webServer,
|
||||
autoAcceptConnections: false
|
||||
});
|
||||
|
||||
if (!wsServer) {
|
||||
log("ERROR: Unable to create WbeSocket server!");
|
||||
}
|
||||
|
||||
// Set up a "connect" message handler on our WebSocket server. This is
|
||||
// called whenever a user connects to the server's port using the
|
||||
// WebSocket protocol.
|
||||
|
||||
wsServer.on('request', function(request) {
|
||||
if (!originIsAllowed(request.origin)) {
|
||||
request.reject();
|
||||
log("Connection from " + request.origin + " rejected.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Accept the request and get a connection.
|
||||
|
||||
var connection = request.accept("json", request.origin);
|
||||
|
||||
// Add the new connection to our list of connections.
|
||||
|
||||
log("Connection accepted from " + connection.remoteAddress + ".");
|
||||
connectionArray.push(connection);
|
||||
|
||||
connection.clientID = nextID;
|
||||
nextID++;
|
||||
|
||||
// Send the new client its token; it send back a "username" message to
|
||||
// tell us what username they want to use.
|
||||
|
||||
var msg = {
|
||||
type: "id",
|
||||
id: connection.clientID
|
||||
};
|
||||
connection.sendUTF(JSON.stringify(msg));
|
||||
|
||||
// Set up a handler for the "message" event received over WebSocket. This
|
||||
// is a message sent by a client, and may be text to share with other
|
||||
// users, a private message (text or signaling) for one user, or a command
|
||||
// to the server.
|
||||
|
||||
connection.on('message', function(message) {
|
||||
if (message.type === 'utf8') {
|
||||
log("Received Message: " + message.utf8Data);
|
||||
|
||||
// Process incoming data.
|
||||
|
||||
var sendToClients = true;
|
||||
msg = JSON.parse(message.utf8Data);
|
||||
var connect = getConnectionForID(msg.id);
|
||||
|
||||
// Take a look at the incoming object and act on it based
|
||||
// on its type. Unknown message types are passed through,
|
||||
// since they may be used to implement client-side features.
|
||||
// Messages with a "target" property are sent only to a user
|
||||
// by that name.
|
||||
|
||||
switch(msg.type) {
|
||||
// Public, textual message
|
||||
case "message":
|
||||
msg.name = connect.username;
|
||||
msg.text = msg.text.replace(/(<([^>]+)>)/ig, "");
|
||||
break;
|
||||
|
||||
// Username change
|
||||
case "username":
|
||||
var nameChanged = false;
|
||||
var origName = msg.name;
|
||||
|
||||
// Ensure the name is unique by appending a number to it
|
||||
// if it's not; keep trying that until it works.
|
||||
while (!isUsernameUnique(msg.name)) {
|
||||
msg.name = origName + appendToMakeUnique;
|
||||
appendToMakeUnique++;
|
||||
nameChanged = true;
|
||||
}
|
||||
|
||||
// If the name had to be changed, we send a "rejectusername"
|
||||
// message back to the user so they know their name has been
|
||||
// altered by the server.
|
||||
if (nameChanged) {
|
||||
var changeMsg = {
|
||||
id: msg.id,
|
||||
type: "rejectusername",
|
||||
name: msg.name
|
||||
};
|
||||
connect.sendUTF(JSON.stringify(changeMsg));
|
||||
}
|
||||
|
||||
// Set this connection's final username and send out the
|
||||
// updated user list to all users. Yeah, we're sending a full
|
||||
// list instead of just updating. It's horribly inefficient
|
||||
// but this is a demo. Don't do this in a real app.
|
||||
connect.username = msg.name;
|
||||
sendUserListToAll();
|
||||
sendToClients = false; // We already sent the proper responses
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert the revised message back to JSON and send it out
|
||||
// to the specified client or all clients, as appropriate. We
|
||||
// pass through any messages not specifically handled
|
||||
// in the select block above. This allows the clients to
|
||||
// exchange signaling and other control objects unimpeded.
|
||||
|
||||
if (sendToClients) {
|
||||
var msgString = JSON.stringify(msg);
|
||||
var i;
|
||||
|
||||
// If the message specifies a target username, only send the
|
||||
// message to them. Otherwise, send it to every user.
|
||||
if (msg.target && msg.target !== undefined && msg.target.length !== 0) {
|
||||
sendToOneUser(msg.target, msgString);
|
||||
} else {
|
||||
for (i=0; i<connectionArray.length; i++) {
|
||||
connectionArray[i].sendUTF(msgString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the WebSocket "close" event; this means a user has logged off
|
||||
// or has been disconnected.
|
||||
connection.on('close', function(reason, description) {
|
||||
// First, remove the connection from the list of connections.
|
||||
connectionArray = connectionArray.filter(function(el, idx, ar) {
|
||||
return el.connected;
|
||||
});
|
||||
|
||||
// Now send the updated user list. Again, please don't do this in a
|
||||
// real application. Your users won't like you very much.
|
||||
sendUserListToAll();
|
||||
|
||||
// Build and output log output for close information.
|
||||
|
||||
var logMessage = "Connection closed: " + connection.remoteAddress + " (" +
|
||||
reason;
|
||||
if (description !== null && description.length !== 0) {
|
||||
logMessage += ": " + description;
|
||||
}
|
||||
logMessage += ")";
|
||||
log(logMessage);
|
||||
});
|
||||
});
|
||||
100
server/src/signal3.js
Normal file
100
server/src/signal3.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const WebSocketServer = require('ws').Server;
|
||||
|
||||
var wss = new WebSocketServer({port: 9090});
|
||||
|
||||
var users = {};
|
||||
|
||||
wss.on('connection', function(connection) {
|
||||
console.log("User connected");
|
||||
|
||||
connection.on('message', (message) => onMessage(connection, message));
|
||||
|
||||
connection.on("close", () => onClose(connection));
|
||||
});
|
||||
|
||||
function sendTo(connection, message) {
|
||||
connection.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
function onClose(connection) {
|
||||
if(connection.name) {
|
||||
delete users[connection.name];
|
||||
|
||||
if(connection.otherName) {
|
||||
console.log("Disconnecting from ", connection.otherName);
|
||||
var conn = users[connection.otherName];
|
||||
conn.otherName = null;
|
||||
|
||||
if(conn != null) {
|
||||
sendTo(conn, {
|
||||
type: "leave"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMessage(connection, message) {
|
||||
var data;
|
||||
|
||||
try {
|
||||
data = JSON.parse(message);
|
||||
} catch (e) {
|
||||
console.log("Invalid JSON");
|
||||
data = {};
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
case "login" :
|
||||
console.log("User logged", data.name);
|
||||
if(users[data.name]) {
|
||||
sendTo(connection, {
|
||||
type: "login",
|
||||
success: false
|
||||
});
|
||||
} else {
|
||||
users[data.name] = connection;
|
||||
connection.name = data.name;
|
||||
|
||||
sendTo(connection, {
|
||||
type: "login",
|
||||
success: true
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "leave" :
|
||||
console.log("Disconnecting from", data.name);
|
||||
var conn = users[data.name];
|
||||
conn.otherName = null;
|
||||
|
||||
//notify the other user so he can disconnect his peer connection
|
||||
/*
|
||||
if(conn != null) {
|
||||
sendTo(conn, {
|
||||
type: "leave"
|
||||
});
|
||||
}*/
|
||||
break;
|
||||
|
||||
case "userlist" :
|
||||
console.log("Send list to", data.name);
|
||||
sendTo(connection, {
|
||||
type: "userlist",
|
||||
list: users
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
if (data.target){
|
||||
var targetConnection = users[data.target];
|
||||
console.log("Forward message from " + data.name + " to " + data.target + " (" + data.type + ")");
|
||||
sendTo(targetConnection, data);
|
||||
} else {
|
||||
sendTo(connection, {
|
||||
type: "error",
|
||||
message: "Command not found: " + data.type
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user