【问题标题】:Perl issues while sending emojis over socket通过套接字发送表情符号时出现 Perl 问题
【发布时间】:2015-11-19 16:02:03
【问题描述】:

我的 Perl 脚本将推送通知发送到 Apple APNS 服务器。除非我尝试发送表情符号(特殊字符),否则它可以工作。

我的代码

use DBI;
use JSON;
use Net::APNS::Persistent;
use Data::Dumper;
use Encode;

my $cfg;
my $apns;

...;

sub connect {
    my ($sandbox, $cert, $key, $pass) = $cfg->getAPNSServer();

    $apns = Net::APNS::Persistent->new({
        sandbox => $sandbox,
        cert    => $cert,
        key     => $key,
    }) or die("[-] Unable to connect to APNS server");

}

sub push {
    my $msg = $_[1];

    Logger::log(5, "[APNS Client] Got message ".Dumper($msg));

    #Encode::_utf8_off($msg);
    utf8::encode($msg);

    my $pack = decode_json($msg);
    my ($token, $payload) = @{$pack};

    Logger::log(5, "Sending push with token: $token and Data: \n".Dumper($payload));

    $apns->queue_notification(
       $token,
       $payload
       );
    $apns->send_queue;
}

所以在 push 子例程中,我使用下面给出的格式传递 JSON 数据。我的问题是表情符号\x{2460}。你可以看到我添加了这一行

utf8::encode($msg);

在解码数据之前。如果我删除此行,则会在解码 JSON 数据时出错

 Wide character in subroutine entry at .....

添加以上行后,我可以解码我的 JSON 数据。但是,当我尝试在下一行写入套接字时 ($apns->send_queue) 给出了

Cannot decode string with wide characters at /usr/lib/perl/5.10/Encode.pm line 176

我该如何解决这个问题?

消息格式(JSON)

["token",
    { 
      "aps":{
          "alert":"Alert: \x{2460}",
          "content-available":1,
          "badge":2,
          "sound":"default.aiff"
       },
       "d":"Meta"
   }
]

自卸车输出

[-] [ 2015-08-25T20:03:15 ] [APNS Client] Got message $VAR1 = "[\"19c360f37681035730a26cckjgkjgkj58b2d20326986f4265ee802c103f51\",{\"aps\":{\"alert\":\"Alert: \x{24bc}\",\"content-available\":1,\"badge\":2,\"sound\":\"default.aiff\"},\"d\":\"Meta\"}]";

[-] [ 2015-08-25T20:03:15 ] Sending push with token: 119c360f37681035730a26cckjgkjgkj58b2d20326986f4265ee802c103f51 and Data:
$VAR1 = {
          'aps' => {
                     'alert' => "Alert: \x{24bc}",
                     'content-available' => 1,
                     'badge' => 2,
                     'sound' => 'default.aiff'
                   },
          'd' => 'Meta'
        };

[x] [ 2015-08-25T20:03:15 ] [APNS Client] Error writing to socket. Reconnecting : Cannot decode string with wide characters at /usr/lib/perl/5.10/Encode.pm line 176.

【问题讨论】:

    标签: json perl sockets unicode apple-push-notifications


    【解决方案1】:

    首先,decode_json 需要使用 UTF-8 编码的 JSON,因此如果您从“解码”的 JSON 开始,则可以像以前那样对其进行编码。

    utf8::encode( my $json_utf8 = $json_uni );
    my $data = decode_json($json_utf8);
    

    但是,使用from_json 会更简单。

    my $data = from_json($json_uni);
    

    现在回答你的问题。写 Net::APNS::Persistent 的人搞砸了。我查看了源代码,他们希望警报消息使用 UTF-8 进行编码。添加以下内容将使您的结构符合模块的不稳定期望:

    utf8::encode(
       ref($payload->{aps}{alert}) eq 'HASH'
          ? $payload->{aps}{alert}{body}
          : $payload->{aps}{alert}
    );
    

    如果您遇到其他问题,我不会感到惊讶。值得注意的是,这些模块使用了 bytes 模块,这是做错事的明确信号。

    【讨论】:

    • 非常感谢@ikegami。不幸的是,这是我发现的唯一 perl apns 模块。
    • 这基本上是 nwellnhof 发布的内容。我刚刚在作曲的过程中被叫走了。请注意,与他的不同,我的解决方案解决了所有有效输入的问题。
    【解决方案2】:

    在发送警报之前,您可能必须对 $payload 中的警报进行 UTF-8 编码。您也可以使用from_json 代替decode_json 来避免第一个编码步骤:

    sub push {
        my $msg = $_[1];
    
        Logger::log(5, "[APNS Client] Got message ".Dumper($msg));
    
        my $pack = from_json($msg);
        my ($token, $payload) = @{$pack};
    
        Logger::log(5, "Sending push with token: $token and Data: \n".Dumper($payload));
    
        # UTF-8 encode before sending.
        utf8::encode($payload->{aps}{alert});
    
        $apns->queue_notification(
           $token,
           $payload
           );
        $apns->send_queue;
    }
    

    【讨论】:

    • 我以前从未使用过from_json;但我想它没有像以前那样解码我的 json;我在倾倒我的 $payload 时得到了一个哈希值。使用令牌发送推送:19c360f37681035730a26ccbdd54d50aa258b2d20326986f4265ee802c103f51 和数据:$VAR1 = 'HASH(0x9471ed8)';但是, utf8::encode($payload->{aps}{alert});作品。所以,我做了两次 utf8::encode 。它以这种方式工作,但有点连线。
    • @user3360140 你注意到我对我的回答所做的修改了吗?
    猜你喜欢
    • 1970-01-01
    • 2014-09-02
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多