通过套接字发送表情符号时出现 Perl 问题
Perl issues while sending emojis over socket
我的 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.
在发送警报之前,您可能必须在 $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;
}
首先,decode_json
期望 JSON 使用 UTF-8 编码,因此如果您从 "decoded" 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 模块,这肯定表明某些操作不正确。
我的 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.
在发送警报之前,您可能必须在 $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;
}
首先,decode_json
期望 JSON 使用 UTF-8 编码,因此如果您从 "decoded" 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 模块,这肯定表明某些操作不正确。