当前位置:首页 > 技术 > 正文内容

如何将本地 WebSocket 服务暴露至公网:使用内网穿透实现远程通信

访客 技术 2026年5月25日 3

WebSocket 开发中的网络限制与解决方案

WebSocket 是一种支持全双工通信的网络协议,广泛应用于实时聊天、数据推送、协同编辑等场景。在开发过程中,开发者通常会在本地启动服务进行调试。然而,默认情况下这类服务仅限局域网访问,无法被外部设备或远程团队成员连接,严重制约了联调效率和测试覆盖范围。

为解决这一问题,可以借助内网穿透工具将本地运行的服务映射到公网。本文将以 Java + Netty 构建的 WebSocket 服务为例,结合轻量级穿透工具,实现安全稳定的远程接入。

搭建基于 Spring Boot 的 WebSocket 服务端

首先准备基础开发环境:

  • JDK 1.8 或更高版本
  • 构建工具:Maven
  • 开发 IDE:IntelliJ IDEA

项目中引入一个基于 Netty 封装的 HTTP 框架,替代默认的 Tomcat 容器以避免端口冲突:

<dependency>
    <groupId>io.github.fzdwx</groupId>
    <artifactId>sky-http-springboot-starter</artifactId>
    <version>0.10.6</version>
</dependency>

注意:需移除或注释掉原有的 spring-boot-starter-web 依赖,防止嵌入式 Web 服务器与 Netty 冲突。

编写 WebSocket 接口逻辑

创建一个 REST 控制器,用于升级 HTTP 连接为 WebSocket 协议:

@GetMapping("/eth/getConnect")
public void establishConnection(HttpServerRequest request) {
    request.upgradeToWebSocket(ws -> {
        // 连接建立时发送欢迎消息
        ws.mountOpen(handler -> {
            ws.send("连接成功,开始聊天吧!");
        });

        // 监听客户端文本消息
        ws.mountText(message -> {
            System.out.println("收到消息: " + message);

            // 模拟服务端回复(从控制台输入)
            Scanner scanner = new Scanner(System.in);
            System.out.print("回复: ");
            String reply = scanner.nextLine();
            ws.send(reply);
        });
    });
}

启动应用后,默认监听 9999 端口。若看到日志输出表明 Netty 已就绪,则服务已正常运行。

配置内网穿透,发布服务至公网

为了让外网设备能够访问该服务,需要将本地 9999 端口映射为公网可访问地址。以下步骤介绍如何通过命令行工具完成隧道配置。

安装客户端(国内用户推荐):

curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash

验证安装是否成功:

cpolar version

登录官网注册账号,获取认证令牌并执行绑定:

cpolar authtoken your_auth_token_here

设置开机自启并启动后台服务:

sudo systemctl enable cpolar
sudo systemctl start cpolar
sudo systemctl status cpolar

服务启动后,访问 http://127.0.0.1:9200 打开管理界面,新建一条 TCP 类型的隧道,将公网请求转发至本地 127.0.0.1:9999

获取公网地址并测试连接

在隧道列表中复制生成的公网连接信息,格式如:
tcp://4.tcp.cpolar.cn:12345

此时,任何位于公网的客户端均可通过此地址连接本地 WebSocket 服务。

使用 Go 编写客户端进行远程测试

选择 Go 语言作为客户端示例,展示跨语言互通能力。

安装 Gorilla WebSocket 库:

go get github.com/gorilla/websocket

编写客户端代码:

package main

import (
    "fmt"
    "log"
    "net/url"

    "github.com/gorilla/websocket"
)

func main() {
    // 替换为实际的公网隧道地址
    serverURL := url.URL{
        Scheme: "ws",
        Host:   "4.tcp.cpolar.cn:12345", // 公网地址
        Path:   "/eth/getConnect",
    }

    conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), nil)
    if err != nil {
        log.Fatal("连接失败:", err)
    }
    defer conn.Close()

    // 接收来自服务端的消息
    go func() {
        for {
            _, msg, _ := conn.ReadMessage()
            fmt.Println("← 收到:", string(msg))
        }
    }()

    // 发送消息给服务端
    go func() {
        var input string
        for {
            fmt.Print("→ 发送: ")
            fmt.Scanln(&input)
            conn.WriteMessage(websocket.TextMessage, []byte(input))
        }
    }()

    select {} // 阻塞主协程
}

验证双向通信

运行客户端程序后,若成功接收"连接成功"提示,说明握手完成。双方可在各自控制台输入内容,实现实时互发消息。

  • 客户端发送 → 服务端控制台打印
  • 服务端手动输入回复 → 客户端即时显示

整个流程无需公网 IP,不修改路由器配置,也无需复杂 DNS 设置,极大简化了远程协作流程。

关于临时地址与固定端口的建议

免费版生成的公网地址具有时效性(通常 24 小时内有效),适用于短期测试。如需长期稳定连接,建议在平台预留一个固定的 TCP 端口,并将其配置进隧道规则中,确保域名和端口不变。

标签: WebSocketNetty

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。