mIRC套接字不一致不起作用

时间:2014-12-31 21:01:42

标签: sockets scripting mirc

我正在为我的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
  }
}

2 个答案:

答案 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                   
}
  • 在HTTP / 1.0中,不需要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 $+ ~
}