peerjs.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/env node
  2. import path from "node:path";
  3. import fs from "node:fs";
  4. const optimistUsageLength = 98;
  5. import yargs from "yargs";
  6. import { hideBin } from "yargs/helpers";
  7. import { PeerServer } from "../src/index.js";
  8. import type { AddressInfo } from "node:net";
  9. import type { CorsOptions } from "cors";
  10. const y = yargs(hideBin(process.argv));
  11. const portEnvIsSet = !!process.env["PORT"];
  12. const opts = y
  13. .usage("Usage: $0")
  14. .wrap(Math.min(optimistUsageLength, y.terminalWidth()))
  15. .options({
  16. expire_timeout: {
  17. demandOption: false,
  18. alias: "t",
  19. describe: "timeout (milliseconds)",
  20. default: 5000,
  21. },
  22. concurrent_limit: {
  23. demandOption: false,
  24. alias: "c",
  25. describe: "concurrent limit",
  26. default: 5000,
  27. },
  28. alive_timeout: {
  29. demandOption: false,
  30. describe: "broken connection check timeout (milliseconds)",
  31. default: 60000,
  32. },
  33. key: {
  34. demandOption: false,
  35. alias: "k",
  36. describe: "connection key",
  37. default: "peerjs",
  38. },
  39. sslkey: {
  40. type: "string",
  41. demandOption: false,
  42. describe: "path to SSL key",
  43. },
  44. sslcert: {
  45. type: "string",
  46. demandOption: false,
  47. describe: "path to SSL certificate",
  48. },
  49. host: {
  50. type: "string",
  51. demandOption: false,
  52. alias: "H",
  53. describe: "host",
  54. },
  55. port: {
  56. type: "number",
  57. demandOption: !portEnvIsSet,
  58. alias: "p",
  59. describe: "port",
  60. },
  61. path: {
  62. type: "string",
  63. demandOption: false,
  64. describe: "custom path",
  65. default: process.env["PEERSERVER_PATH"] ?? "/",
  66. },
  67. allow_discovery: {
  68. type: "boolean",
  69. demandOption: false,
  70. describe: "allow discovery of peers",
  71. },
  72. proxied: {
  73. type: "boolean",
  74. demandOption: false,
  75. describe: "Set true if PeerServer stays behind a reverse proxy",
  76. default: false,
  77. },
  78. cors: {
  79. type: "string",
  80. array: true,
  81. describe: "Set the list of CORS origins",
  82. },
  83. })
  84. .boolean("allow_discovery")
  85. .parseSync();
  86. if (!opts.port) {
  87. // .port is only not set if the PORT env var is set
  88. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  89. opts.port = parseInt(process.env["PORT"]!);
  90. }
  91. if (opts.cors) {
  92. opts["corsOptions"] = {
  93. origin: opts.cors,
  94. } satisfies CorsOptions;
  95. }
  96. process.on("uncaughtException", function (e) {
  97. console.error("Error: " + e.toString());
  98. });
  99. if (opts.sslkey ?? opts.sslcert) {
  100. if (opts.sslkey && opts.sslcert) {
  101. opts["ssl"] = {
  102. key: fs.readFileSync(path.resolve(opts.sslkey)),
  103. cert: fs.readFileSync(path.resolve(opts.sslcert)),
  104. };
  105. } else {
  106. console.error(
  107. "Warning: PeerServer will not run because either " +
  108. "the key or the certificate has not been provided.",
  109. );
  110. process.exit(1);
  111. }
  112. }
  113. const userPath = opts.path;
  114. const server = PeerServer(opts, (server) => {
  115. const { address: host, port } = server.address() as AddressInfo;
  116. console.log(
  117. "Started PeerServer on %s, port: %s, path: %s",
  118. host,
  119. port,
  120. userPath || "/",
  121. );
  122. const shutdownApp = () => {
  123. server.close(() => {
  124. console.log("Http server closed.");
  125. process.exit(0);
  126. });
  127. };
  128. process.on("SIGINT", shutdownApp);
  129. process.on("SIGTERM", shutdownApp);
  130. });
  131. server.on("connection", (client) => {
  132. console.log(`Client connected: ${client.getId()}`);
  133. });
  134. server.on("disconnect", (client) => {
  135. console.log(`Client disconnected: ${client.getId()}`);
  136. });