You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Perl的Net::WebSocket::Server握手阶段获取JS传入的UserID

在Net::WebSocket::Server握手阶段获取查询字符串中的UserID

当然可以做到!WebSocket握手本质是一个HTTP请求,你在客户端URL里添加的查询字符串会被包含在初始的握手请求中,而Net::WebSocket::Server的handshake回调正好提供了访问这个请求细节的途径。

下面是具体的实现方法,我准备了两种方案:一种依赖URI模块(更简洁),另一种手动解析(无需额外依赖),你可以根据需求选择。

完整代码示例

方案1:使用URI模块解析推荐

URI是Perl处理URL的标准工具,Net::WebSocket::Server通常会间接依赖它,所以你大概率已经安装了这个模块。

use Net::WebSocket::Server;
use URI;

Net::WebSocket::Server->new(
    listen => $ssl,
    silence_max => 3600,
    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(
            handshake => sub {
                my ($conn, $handshake) = @_;
                
                # 从握手请求中获取URI对象
                my $request_uri = $handshake->req->uri;
                
                # 直接提取UserID参数
                my $user_id = $request_uri->query_param('UserID');
                
                if (defined $user_id) {
                    print "握手阶段获取到UserID: $user_id\n";
                    # 把UserID绑定到连接对象上,后续回调中随时可以使用
                    $conn->{user_id} = $user_id;
                } else {
                    # 如果没有提供UserID,可选择直接拒绝连接
                    $conn->disconnect();
                    print "未提供UserID,已断开连接\n";
                }
            },
        );
        # 可选:后续消息回调中使用存储的UserID
        $conn->on(
            message => sub {
                my ($conn, $msg) = @_;
                print "收到UserID[$conn->{user_id}]的消息: $msg\n";
            },
        );
    },
)->start;

方案2:手动解析查询字符串无需额外模块

如果不想依赖URI模块,也可以手动拆分并解码查询字符串:

use Net::WebSocket::Server;

Net::WebSocket::Server->new(
    listen => $ssl,
    silence_max => 3600,
    on_connect => sub {
        my ($serv, $conn) = @_;
        $conn->on(
            handshake => sub {
                my ($conn, $handshake) = @_;
                
                # 获取查询字符串部分
                my $query_string = $handshake->req->uri->query;
                
                my %query_params;
                if ($query_string) {
                    # 拆分键值对,用split的第三个参数避免值中包含=的情况
                    foreach my $pair (split /&/, $query_string) {
                        my ($key, $value) = split /=/, $pair, 2;
                        next unless defined $key && defined $value;
                        
                        # URL解码处理(比如把%20转成空格)
                        $value =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
                        $query_params{$key} = $value;
                    }
                }
                
                my $user_id = $query_params{UserID};
                if (defined $user_id) {
                    print "握手阶段获取到UserID: $user_id\n";
                    $conn->{user_id} = $user_id;
                } else {
                    $conn->disconnect();
                    print "未提供UserID,已断开连接\n";
                }
            },
        );
    },
)->start;

关键说明

  1. $handshake对象的作用:handshake回调中的$handshake参数包含了完整的HTTP握手请求信息,通过$handshake->req可以拿到HTTP::Request实例,进而获取请求的URI细节。
  2. 存储UserID:把UserID存在$conn对象的哈希属性中(比如$conn->{user_id}),这样后续在message、disconnect等回调里都能直接访问到这个用户标识。
  3. 合法性校验:你可以在拿到UserID后做合法性验证(比如查询数据库确认用户存在),如果验证不通过,直接调用$conn->disconnect()拒绝连接即可。

内容的提问来源于stack exchange,提问作者Xerix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:12:21