我如何构建 Ngrok Alternative
以下是我所构建内容的简要介绍
Ngrok是一款非常棒的工具,它可以帮助开发人员以最小的代价将本地主机暴露到互联网上。有一天,我打算与客户分享一个本地项目,但不想将其部署到其他地方。但这次我需要暴露两个端口:一个运行前端,另一个运行项目的后端。我发现 ngrok 的免费方案一次只允许一个隧道。当天晚些时候,我还发现请求数限制为每分钟 40 个。
砰!好主意!
如果我不用每月支付 5 美元,自己开发一个替代方案怎么样?
开发人员就是这么做的,对吧?我还想到了把它开源。
是时候制定计划了。
显然,这包括三个部分:
- 具有命令行工具(cli)的开发人员
- 代理服务器
- 带有浏览器的客户端。
我确信至少需要以下步骤才能使其发挥作用:
- 开发人员通过具有端口号的 CLI 连接到服务器:
jprq 8000
- 服务器以分配的域进行响应。
amazing-coder.jprq.live
- 客户端在浏览器中打开域名:
https://amazing-coder.jprq.live
- 服务器接收请求并将其发送给cli。
- CLI 向给定端口的本地主机发出请求并将响应发送到服务器。
- 服务器将从 CLI 收到的响应返回给客户端。
命令行和服务器需要进行双向通信。精心管理的 TCP 套接字可以很好地完成这项工作,但实现起来会耗费很长时间。
我决定使用 WebSocket 协议。你可能知道,WebSocket 是一种逐跳协议,遗憾的是,我的 ngrok 替代方案现在无法支持轮询和 HTTP 流(因为它们永远不会结束或持续太长时间)。
该命令行工具是用 Python 编写的,并发布到 PyPy 上。目前,我正在用 JavaScript 实现命令行,以便发布到 npm,纯粹出于兴趣。服务器端是用 Golang 编写的。我认为选择 Golang 是最好的决定,因为它在 Goroutine 之间共享数据非常方便,而且我亲身经历了 Goroutine 内存泄漏的痛苦。通过这个项目,我现在对内存泄漏有了更深入的理解。
我在实现客户端-服务器通信时犯的另一个虽小但影响深远的错误是使用 JSON。我是在添加了文件处理功能后才意识到这一点的。JSON 只能序列化字符串。为了将文件内容(字节)转换为字符串,我需要对它们进行 Base64 编码。事实证明,这是一个 CPU 密集型的过程。我认为最好使用 BSON。
该项目是开源的,期待您的贡献。欢迎访问 GitHub 仓库github.com/azimjohn/jprq。
继续建设,
干杯。