我正在为我的Twitch机器人开发一个新的uptime命令,我遇到套接字问题。我正在尝试使用此页http://api.twitch.tv/api/channels/duilio1337来检查流媒体是否在线。它有时工作正常,但有时它会读取页面标题而不是页面。似乎是随机的。
alias uptimecheck {
echo -a CHECKING CHANNEL $1 STATUS
%uptimeurl = /api/channels/ $+ $1
%uptimecheckchan = $1
sockopen wuptime api.twitch.tv 80
}
on *:sockopen:wuptime: {
sockwrite -n $sockname GET %uptimeurl HTTP/1.0
sockwrite -n $sockname User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
sockwrite -n $sockname Host: api.twitch.tv
sockwrite -n $sockname Accept-Language: en-us
sockwrite -n $sockname Accept: */*
sockwrite -n $sockname
}
on *:sockread:wuptime: {
if ($sockerr) {
echo -a UPTIME Connection Error.
halt
}
else {
sockread -f %uptimeliverail
if ($sockbr == 0) return
;echo -a %uptimeliverail
}
}
on *:sockclose:wuptime: {
var %TEMPliverail $mid(%uptimeliverail, $calc($pos(%uptimeliverail, "twitch_liverail_id") + 21), 4)
if (%TEMPliverail == null) {
set %uptimelive. $+ %uptimecheckchan 0
}
else if (%TEMPliverail isnum) {
set %uptimelive. $+ %uptimecheckchan 1
}
}
答案 0 :(得分:0)
http://api.twitch.tv/api/channels/duilio1337的内容只是:
{"display_name":"duilio1337","game":null,"status":"Test","fight_ad_block":false,"_id":47890122,"name":"duilio1337","partner":false,"comscore_id":null,"comscore_c6":null,"twitch_liverail_id":null,"hide_ads_for_subscribers":false,"liverail_id":null,"ppv":false,"video_banner":null,"steam_id":null,"broadcaster_software":"unknown_rtmp","prerolls":true,"postrolls":true,"product_path":""}
它不是HTML页面,所以你的意思是:它读取页面标题而不是页面。?
也许你可以更好地解释你的问题。
无论如何......我认为在sockopen
事件中你的目的应该足以发送GET和主机标题:
on *:sockopen:wuptime: {
sockwrite -nt $sockname GET %uptimeurl HTTP/1.1
sockwrite -nt $sockname Host: api.twitch.tv
sockwrite $sockname $crlf
}
Host
,但不会受到伤害。在HTTP / 1.1中是必需的。-t
参数,以避免将&
视为二进制变量。sockwrite $sockname $crlf
是一种更明确的方式来完成HTTP请求,与您的sockwrite -n $sockname
等效(IIRC)(因为-n
添加了$crlf
)。< / LI>
此外,您的sockread
事件通常应该类似于:
on *:sockread:wuptime: {
if ($sockerr) {
;error msg code here
return
}
var %data
sockread %data
;your code here
unset %data
}
halt
,该命令用于立即停止任何进一步处理。在大多数情况下,使用return
更合适。 if-else
条件。值得注意的是,每次服务器回复一行时,都会启动sockread
事件。
答案 1 :(得分:0)
服务器最有可能返回
Vary: Accept Encoding
在响应标头中。尝试用
替换Accept */*
行
sockwrite -n $sockname Accept: gzip
看看会发生什么。它很可能会返回压缩的二进制数据(而不是超时,或根本不返回任何内容)。问题是,mIRC无法解压缩,也不支持gzip解码。昨晚我遇到了同样的问题,这就是我为使用mIRC套接字并需要获取gzip内容的任何人解决的问题。
首先请确保将上面的标题更改为Accept: gzip
其次,从http://www.7-zip.org/a/7za920.zip获取7za(Windows控制台为7-zip)的副本。解压缩7za并将其放在c:\program files (x86)\mIRC\
文件夹中,或放在mirc.exe所在的位置。
我修改了OP的*on:sockread:
块以获取并提取下面的gzip内容:
on *:sockread:wuptime:{
var %bare $rand(423539,999999)
var %gz 1
:play
var %dg
sockread %dg
:wile
if ( %gz = 2 ) {
sockread -f &gzd
}
if ($sockerr) {
return
}
if ( %gz = 2 ) {
while ($sockbr) {
bwrite %bare -1 -1 &gzd
sockread -f &gzd
}
}
if ($sockbr == 0) {
sockclose $sockname
echo -at closed
run -h 7za.exe e %bare
.timer 1 2 wuptimeparse %bare
return
}
if ( %dg = $null) {
var %gz 2
goto wile
}
goto play
}
这可能很粗糙,但是一旦标题完成返回,它就会启动bwrite
一个随机文件,一旦$sockbr
为空,它就会对压缩的二进制数据运行7zip。下面的别名将在几秒钟内调用(7zip的时间来完成它的魔法......你可以用更加优雅的方式来做这件事),以便吐出你正在寻找的明文JSON。请注意,如果您示例中的JSON很大(超过4000个字符),则需要将其作为带有bread
的binvar读取,因为字符串太大而无法容纳变量。
alias wuptimeparse {
var %file $1
var %bare $read(%file $+ ~,1)
echo %bare
;do something with %bare
.timer 1 1 remove %file
.timer 1 1 remove %file $+ ~
}