2.5.13 • Published 4 months ago

peergate-server v2.5.13

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

PeerGate


🌐 English

PeerGate is a lightweight framework that enables direct peer-to-peer communication between browsers and Node.js applications using WebRTC technology. It allows you to create API endpoints that can be accessed directly from browsers without requiring a public IP address or complex server setup.

✨ Features

  • Peer-to-peer communication: Direct connection between browsers and Node.js without intermediary servers
  • No public IP required: Works behind NAT and firewalls
  • Simple API: Express-like routing system
  • Bidirectional communication: Both client and server can initiate requests
  • File upload support: Built-in middleware for handling file uploads
  • Middleware support: Add authentication, logging, and more
  • Parameterized routes: Support for dynamic route parameters
  • Error handling: Built-in error handling mechanism
  • Promise-based: Modern async/await compatible API

🚀 Getting Started

Installation

npm install peergate-server

Basic Server Example

const peergate = require("peergate-server");

// Create PeerGate server
const app = peergate({
  debug: true,
  peerId: "my-server", // Optional: fixed server ID for testing
});

// Register route handler for /hello
app.seek("/hello", (seek, pom) => {
  console.log("Hello request received:", seek.body);

  // Send response
  pom.send({
    message: "Hello from PeerGate server!",
    timestamp: Date.now(),
    receivedData: seek.body,
  });
});

// Initialize server
app
  .init()
  .then((peerId) => {
    console.log(`Server started with PeerID: ${peerId}`);
  })
  .catch((err) => {
    console.error("Server startup failed:", err);
  });

Basic Client Example

Create an HTML file with the following content:

<!DOCTYPE html>
<html>
  <head>
    <title>PeerGate Client Example</title>
    <script src="https://unpkg.com/peerjs@1.5.1/dist/peerjs.min.js"></script>
    <script src="path/to/peergate-client.js"></script>
  </head>
  <body>
    <h1>PeerGate Client Example</h1>
    <div id="output"></div>

    <script>
      // Create PeerGate client
      const client = createPeerGateClient({
        serverId: "my-server", // Server's PeerID
        debug: true,
      });

      // Connect event
      client.on("connected", () => {
        document.getElementById("output").innerHTML = "Connected to server!";

        // Send request to /hello endpoint
        client
          .seek("/hello", { name: "John", age: 30 })
          .then((response) => {
            document.getElementById(
              "output"
            ).innerHTML = `<pre>${JSON.stringify(response, null, 2)}</pre>`;
          })
          .catch((err) => {
            document.getElementById(
              "output"
            ).innerHTML = `Error: ${err.message}`;
          });
      });

      // Error event
      client.on("error", (err) => {
        document.getElementById("output").innerHTML = `Error: ${err.message}`;
      });
    </script>
  </body>
</html>

📚 API Reference

Server API

Creating a Server
const peergate = require("peergate-server");

const app = peergate({
  debug: true, // Enable debug mode
  headless: true, // Run browser in headless mode
  peerId: "my-server", // Optional: fixed server ID
  persistPeerId: true, // Save PeerID to .env file
  reconnectDelay: 5000, // Reconnect delay in ms
});
Defining Routes
// Basic route
app.seek("/hello", (seek, pom) => {
  pom.send({ message: "Hello World!" });
});

// Route with parameters
app.seek("/users/:id", (seek, pom) => {
  const userId = seek.params.id;
  // ... fetch user data
  pom.send({ id: userId, name: "User Name" });
});

// Error handling
app.seek("/error-example", (seek, pom) => {
  pom.error("not_found", "Resource not found");
});
Middleware
// Add middleware
app.use(async (seek, pom, next) => {
  console.log(`Request received: ${seek.path}`);
  await next();
  console.log(`Response sent for: ${seek.path}`);
});

// Authentication middleware
app.use((seek, pom, next) => {
  if (!seek.body.token) {
    return pom.error("unauthorized", "Authentication required");
  }
  // Validate token...
  next();
});

// File upload middleware
app.use(
  app.fileMiddleware({
    uploadDir: path.join(__dirname, "uploads"),
    allowedTypes: ["jpg", "png", "pdf"],
    maxFileSize: 10 * 1024 * 1024, // 10MB
    maxFiles: 5,
  })
);
Server Initialization
app
  .init()
  .then((peerId) => {
    console.log(`Server started with PeerID: ${peerId}`);
  })
  .catch((err) => {
    console.error("Server startup failed:", err);
  });
Closing the Server
app.close().then(() => {
  console.log("Server closed");
});

Client API

Creating a Client
const client = createPeerGateClient({
  serverId: "my-server", // Server's PeerID
  debug: true, // Enable debug mode
  connectionTimeout: 10000, // Connection timeout in ms
  requestTimeout: 30000, // Request timeout in ms
  peerOptions: {}, // PeerJS options
});

Parameterized Routes

// Server-side
app.seek("/items/:category/:id", (seek, pom) => {
  const { category, id } = seek.params;
  console.log(`Fetching item ${id} from category ${category}`);

  // ... fetch item data
  pom.send({ category, id, name: "Item Name" });
});

// Client-side
client.seek("/items/electronics/123", { detail: true }).then((item) => {
  console.log("Item:", item);
});

🌟 Benefits of Using PeerGate

  1. No Public IP Required: Works behind NAT and firewalls without port forwarding
  2. Reduced Server Costs: Direct P2P communication reduces server bandwidth usage
  3. Lower Latency: Direct connections provide faster communication
  4. Simplified Deployment: No need for complex server infrastructure
  5. Familiar API: Express-like routing system makes it easy to learn
  6. Secure Communication: WebRTC provides encrypted connections by default
  7. Offline Capability: Can work without internet connection in local networks
  8. Scalability: Distributed architecture scales naturally with users

📋 Requirements

  • Node.js 14.0.0 or higher
  • Modern browser with WebRTC support (Chrome, Firefox, Safari, Edge)

📝 License

MIT


🌐 中文

PeerGate 是一个轻量级框架,使用 WebRTC 技术实现浏览器和 Node.js 应用程序之间的直接点对点通信。它允许你创建可以直接从浏览器访问的 API 端点,无需公网 IP 地址或复杂的服务器设置。

✨ 特点

  • 点对点通信:浏览器和 Node.js 之间无需中间服务器的直接连接
  • 无需公网 IP:可在 NAT 和防火墙后正常工作
  • 简单的 API:类似 Express 的路由系统
  • 双向通信:客户端和服务器都可以发起请求
  • 文件上传支持:内置中间件处理文件上传
  • 中间件支持:添加认证、日志记录等功能
  • 参数化路由:支持动态路由参数
  • 错误处理:内置错误处理机制
  • 基于 Promise:兼容现代 async/await API

🚀 快速开始

安装

npm install peergate-server

基本服务器示例

const peergate = require("peergate-server");

// 创建 PeerGate 服务器
const app = peergate({
  debug: true,
  peerId: "my-server", // 可选:用于测试的固定服务器 ID
});

// 注册 /hello 路由处理程序
app.seek("/hello", (seek, pom) => {
  console.log("收到 Hello 请求:", seek.body);

  // 发送响应
  pom.send({
    message: "来自 PeerGate 服务器的问候!",
    timestamp: Date.now(),
    receivedData: seek.body,
  });
});

// 初始化服务器
app
  .init()
  .then((peerId) => {
    console.log(`服务器已启动,PeerID: ${peerId}`);
  })
  .catch((err) => {
    console.error("服务器启动失败:", err);
  });

基本客户端示例

创建一个包含以下内容的 HTML 文件:

<!DOCTYPE html>
<html>
  <head>
    <title>PeerGate 客户端示例</title>
    <script src="https://unpkg.com/peerjs@1.5.1/dist/peerjs.min.js"></script>
    <script src="path/to/peergate-client.js"></script>
  </head>
  <body>
    <h1>PeerGate 客户端示例</h1>
    <div id="output"></div>

    <script>
      // 创建 PeerGate 客户端
      const client = createPeerGateClient({
        serverId: "my-server", // 服务器的 PeerID
        debug: true,
      });

      // 连接事件
      client.on("connected", () => {
        document.getElementById("output").innerHTML = "已连接到服务器!";

        // 发送请求到 /hello 端点
        client
          .seek("/hello", { name: "张三", age: 30 })
          .then((response) => {
            document.getElementById(
              "output"
            ).innerHTML = `<pre>${JSON.stringify(response, null, 2)}</pre>`;
          })
          .catch((err) => {
            document.getElementById(
              "output"
            ).innerHTML = `错误: ${err.message}`;
          });
      });

      // 错误事件
      client.on("error", (err) => {
        document.getElementById("output").innerHTML = `错误: ${err.message}`;
      });
    </script>
  </body>
</html>

📚 API 参考

服务器 API

创建服务器
const peergate = require("peergate-server");

const app = peergate({
  debug: true, // 启用调试模式
  headless: true, // 在无头模式下运行浏览器
  peerId: "my-server", // 可选:固定服务器 ID
  persistPeerId: true, // 将 PeerID 保存到 .env 文件
  reconnectDelay: 5000, // 重连延迟(毫秒)
});
定义路由
// 基本路由
app.seek("/hello", (seek, pom) => {
  pom.send({ message: "你好,世界!" });
});

// 带参数的路由
app.seek("/users/:id", (seek, pom) => {
  const userId = seek.params.id;
  // ... 获取用户数据
  pom.send({ id: userId, name: "用户名" });
});

// 错误处理
app.seek("/error-example", (seek, pom) => {
  pom.error("not_found", "未找到资源");
});
中间件
// 添加中间件
app.use(async (seek, pom, next) => {
  console.log(`收到请求: ${seek.path}`);
  await next();
  console.log(`已发送响应: ${seek.path}`);
});

// 认证中间件
app.use((seek, pom, next) => {
  if (!seek.body.token) {
    return pom.error("unauthorized", "需要认证");
  }
  // 验证令牌...
  next();
});

// 文件上传中间件
app.use(
  app.fileMiddleware({
    uploadDir: path.join(__dirname, "uploads"),
    allowedTypes: ["jpg", "png", "pdf"],
    maxFileSize: 10 * 1024 * 1024, // 10MB
    maxFiles: 5,
  })
);
服务器初始化
app
  .init()
  .then((peerId) => {
    console.log(`服务器已启动,PeerID: ${peerId}`);
  })
  .catch((err) => {
    console.error("服务器启动失败:", err);
  });
关闭服务器
app.close().then(() => {
  console.log("服务器已关闭");
});

客户端 API

创建客户端
const client = createPeerGateClient({
  serverId: "my-server", // 服务器的 PeerID
  debug: true, // 启用调试模式
  connectionTimeout: 10000, // 连接超时(毫秒)
  requestTimeout: 30000, // 请求超时(毫秒)
  peerOptions: {}, // PeerJS 选项
});
发送请求
// 基本请求
client
  .seek("/hello", { name: "张三" })
  .then((response) => {
    console.log("响应:", response);
  })
  .catch((err) => {
    console.error("错误:", err);
  });

// 使用 async/await
async function fetchData() {
  try {
    const response = await client.seek("/users/123", { detail: true });
    console.log("用户数据:", response);
  } catch (err) {
    console.error("获取用户时出错:", err);
  }
}
事件处理
// 连接事件
client.on("connected", () => {
  console.log("已连接到服务器");
});

client.on("disconnected", () => {
  console.log("已断开与服务器的连接");
});

client.on("error", (err) => {
  console.error("错误:", err);
});

// 一次性事件
client.once("connected", () => {
  console.log("首次连接已建立");
});
关闭连接
client.close();

🔧 高级用法

自定义错误处理

// 服务器端
app.seek("/custom-error", (seek, pom) => {
  if (!seek.body.id) {
    return pom.error("validation_error", "ID 是必需的");
  }

  // 处理请求...
});

// 客户端
client.seek("/custom-error", {}).catch((err) => {
  if (err.code === "validation_error") {
    console.error("验证失败:", err.message);
  } else {
    console.error("未知错误:", err);
  }
});

参数化路由

// 服务器端
app.seek("/items/:category/:id", (seek, pom) => {
  const { category, id } = seek.params;
  console.log(`获取类别 ${category} 中的物品 ${id}`);

  // ... 获取物品数据
  pom.send({ category, id, name: "物品名称" });
});

// 客户端
client.seek("/items/electronics/123", { detail: true }).then((item) => {
  console.log("物品:", item);
});

🌟 使用 PeerGate 的好处

  1. 无需公网 IP:无需端口转发,可在 NAT 和防火墙后正常工作
  2. 降低服务器成本:直接的 P2P 通信减少服务器带宽使用
  3. 更低的延迟:直接连接提供更快的通信
  4. 简化部署:无需复杂的服务器基础设施
  5. 熟悉的 API:类似 Express 的路由系统易于学习
  6. 安全通信:WebRTC 默认提供加密连接
  7. 离线能力:可在本地网络中无需互联网连接工作
  8. 可扩展性:分布式架构自然随用户扩展

📋 要求

  • Node.js 14.0.0 或更高版本
  • 支持 WebRTC 的现代浏览器(Chrome、Firefox、Safari、Edge)

📝 许可证

MIT

文件上传处理

PeerGate 提供内置中间件用于处理来自客户端的文件上传。

基本文件上传配置
const peergate = require("peergate-server");
const path = require("path");

const app = peergate({
  debug: true,
  // 启用文件上传并使用默认设置
  fileUpload: {
    enabled: true,
    uploadDir: path.join(__dirname, "uploads"),
    allowedTypes: ["jpg", "jpeg", "png", "pdf"],
    maxFileSize: 10 * 1024 * 1024, // 10MB
    maxFiles: 5,
  },
});

// 处理文件上传
app.seek("/upload", (seek, pom) => {
  // Check if files were uploaded
  if (!seek.body.file) {
    return pom.error("no_file", "No file uploaded");
  }

  const fileInfo = seek.body.file;
  console.log("File uploaded:", fileInfo);

  pom.send({
    success: true,
    message: "File uploaded successfully",
    file: {
      name: fileInfo.originalName,
      size: fileInfo.size,
      type: fileInfo.type,
      path: fileInfo.path,
    },
  });
});
2.5.13

4 months ago

2.5.11

4 months ago

2.5.8

4 months ago

2.5.7

4 months ago

2.5.6

4 months ago

2.5.0

4 months ago

2.4.7

4 months ago