Scala中“ {}”消息后#slack RTM api断开连接

aut*_*nix 2 scala websocket netty slack-api

我目前正在尝试使用可用的RTM API与Scala创建#slack机器人。

我设法获得了一个基本的功能性机器人,该机器人以“乒乓”响应“ ping”。

我目前遇到的问题是,在打开流之后,Websocket连接每隔几分钟就会有系统地关闭。

我目前正在使用以下库用于websocket:https : //github.com/jfarcand/WCS

在这一点上,我不确定{}从#slack RTM流接收到的空JSON消息()之后是什么原因导致连接断开。

任何帮助将不胜感激。

这是相关的连接和侦听器代码:

def connect(): Unit ={

    if(rec_url == "")
      slack = ws.open(rtm_url)
    else {
      h.debug("Attempting to reconnect")
      slack = WebSocket().open(rec_url) // TODO: need to completely close the connection before trying to create a new one.
    }


    initRTM()
  }

  // Initialize Real Time Messaging
  def initRTM(): Unit = {

    h.debug("\nOpening Real Time Messaging socket")

    slack.listener(new TextListener {

        override def onOpen: Unit = {
          h.debug("Websocket connection open")
          status = 1
        }

        override def onClose: Unit = {
          h.debug("Websocket connection closed, reconnecting...")
          slack.shutDown

          status = 0
        }

        override def onError(t: Throwable): Unit ={
          h.debug("Websocket Error encountered")
          t.printStackTrace()
          h.debug(t.getMessage)
        }

        override def onMessage(message: String) {
          h.debug("Message received: "+message)
          val body: JsValue = Json.parse(message)

          try {

            if(body.as[JsObject].keys.contains("type")){
              val m_type = (body \ "type").as[String]

              m_type match {

                case "hello" => ;
                case "reconnect_url" => setReconnectUrl((body \ "url").as[String])
                case "message" => processMessage(body)
                case _ => h.debug("Unprocessed message type: " + m_type)

              }
            }
          } catch {
            case e: Exception=> e.printStackTrace()
          }
        }

      })

    while(slack.isOpen){

    }

    h.debug("connection is closed")

    connect()


  }
Run Code Online (Sandbox Code Playgroud)

这是控制台的输出:

Opening Real Time Messaging socket
INFO - Websocket connection open
INFO - Message received: {"type":"hello"}
INFO - Message received: {"reply_to":0,"type":"message","channel":"D1NCSAU12","user":"U1NCSAU0L","text":"pong","ts":"1467558776.000079"}
INFO - Message received: {"type":"reconnect_url","url":"wss://mpmulti-c6k1.slack-msgs.com/websocket/x4UkvMwZeNqFuyZ_YsxjLNi_OIOzqHisL6sHC3DB0QRnKoG-VH8Qr361SlSprlWb6WjzDhw6j5Pj0FiFFYTjoiCLwM-i863os0xWkjUGJJbUoKUmtlG22e3lTTAFuuIFg2TTI7W-0XfU4HJB2nvbjy_hKCwVQ7uIIlrr6fYi_ms="}
INFO - Reconnect URL Set to: wss://mpmulti-c6k1.slack-msgs.com/websocket/x4UkvMwZeNqFuyZ_YsxjLNi_OIOzqHisL6sHC3DB0QRnKoG-VH8Qr361SlSprlWb6WjzDhw6j5Pj0FiFFYTjoiCLwM-i863os0xWkjUGJJbUoKUmtlG22e3lTTAFuuIFg2TTI7W-0XfU4HJB2nvbjy_hKCwVQ7uIIlrr6fYi_ms=
INFO - Message received: {"type":"presence_change","presence":"active","user":"U1NCSAU0L"}
INFO - Unprocessed message type: presence_change
11:23:18.790 [Hashed wheel timer #1] DEBUG com.ning.http.client.providers.netty.channel.pool.DefaultChannelPool - Closed 0 connections out of 0 in 0ms
INFO - Message received: {"type":"user_typing","channel":"D1NCSAU12","user":"U1MP4A19R"}
INFO - Unprocessed message type: user_typing
INFO - Message received: {"type":"message","channel":"D1NCSAU12","user":"U1MP4A19R","text":"ping","ts":"1467559430.000080","team":"T1MQWNFR8"}
INFO - User typed 'ping'
INFO - Answer: {"id":0,"type":"message","channel":"D1NCSAU12","text":"pong"}
INFO - Message received: {"ok":true,"reply_to":0,"ts":"1467559430.000081","text":"pong"}
INFO - Message received: {"type":"user_typing","channel":"D1NCSAU12","user":"U1MP4A19R"}
INFO - Unprocessed message type: user_typing
INFO - Message received: {"type":"message","channel":"D1NCSAU12","user":"U1MP4A19R","text":"ping","ts":"1467559432.000082","team":"T1MQWNFR8"}
INFO - User typed 'ping'
INFO - Answer: {"id":1,"type":"message","channel":"D1NCSAU12","text":"pong"}
INFO - Message received: {"ok":true,"reply_to":1,"ts":"1467559432.000083","text":"pong"}
INFO - Message received: {"type":"user_typing","channel":"D1NCSAU12","user":"U1MP4A19R"}
INFO - Unprocessed message type: user_typing
INFO - Message received: {"type":"message","channel":"D1NCSAU12","user":"U1MP4A19R","text":"ping","ts":"1467559434.000084","team":"T1MQWNFR8"}
INFO - User typed 'ping'
INFO - Answer: {"id":2,"type":"message","channel":"D1NCSAU12","text":"pong"}
INFO - Message received: {"ok":true,"reply_to":2,"ts":"1467559434.000085","text":"pong"}
INFO - Message received: {"type":"user_typing","channel":"D1NCSAU12","user":"U1MP4A19R"}
INFO - Unprocessed message type: user_typing
INFO - Message received: {"type":"message","channel":"D1NCSAU12","user":"U1MP4A19R","text":"ping","ts":"1467559448.000086","team":"T1MQWNFR8"}
INFO - User typed 'ping'
INFO - Answer: {"id":3,"type":"message","channel":"D1NCSAU12","text":"pong"}
INFO - Message received: {"ok":true,"reply_to":3,"ts":"1467559448.000087","text":"pong"}
INFO - Message received: {"type":"user_typing","channel":"D1NCSAU12","user":"U1MP4A19R"}
INFO - Unprocessed message type: user_typing
INFO - Message received: {"type":"message","channel":"D1NCSAU12","user":"U1MP4A19R","text":"ping ping","ts":"1467559452.000088","team":"T1MQWNFR8"}
11:24:18.889 [Hashed wheel timer #1] DEBUG com.ning.http.client.providers.netty.channel.pool.DefaultChannelPool - Closed 0 connections out of 0 in 0ms
INFO - Message received: {"type":"reconnect_url","url":"wss://mpmulti-lbww.slack-msgs.com/websocket/u61Fem7nt3c1DP35C1So6S-Q3QnP0wcY4BeKMG6GZBpjo32E_rGM0YhwH-M_i6uGdezSgzr8R6BmM4eC7ZcwGaAR38GRi2VFyEM7REgtCO0Hd6FAsguHS63TwCI65UwBCkcS_gEFdpoI5tD0az4cBWtdfj1yXbn1iOwpiH_BALg="}
INFO - Reconnect URL Set to: wss://mpmulti-lbww.slack-msgs.com/websocket/u61Fem7nt3c1DP35C1So6S-Q3QnP0wcY4BeKMG6GZBpjo32E_rGM0YhwH-M_i6uGdezSgzr8R6BmM4eC7ZcwGaAR38GRi2VFyEM7REgtCO0Hd6FAsguHS63TwCI65UwBCkcS_gEFdpoI5tD0az4cBWtdfj1yXbn1iOwpiH_BALg=
11:25:18.989 [Hashed wheel timer #1] DEBUG com.ning.http.client.providers.netty.channel.pool.DefaultChannelPool - Closed 0 connections out of 0 in 0ms
INFO - Message received: {}
11:26:13.918 [New I/O worker #1] DEBUG com.ning.http.client.providers.netty.handler.Processor - Channel Closed: [id: 0x0e0d06c0, /192.168.99.102:46345 :> mpmulti-6wbl.slack-msgs.com/54.172.207.190:443] with attribute NettyResponseFuture{currentRetry=5,
    isDone=true,
    isCancelled=false,
    asyncHandler=com.ning.http.client.ws.WebSocketUpgradeHandler@e9cba57,
    nettyRequest=com.ning.http.client.providers.netty.request.NettyRequest@b3f8453,
    content=NettyWebSocket{channel=[id: 0x0e0d06c0, /192.168.99.102:46345 :> mpmulti-6wbl.slack-msgs.com/54.172.207.190:443]},
    uri=wss://mpmulti-6wbl.slack-msgs.com/websocket/0WNxIQsK_mzw561vkxWrN4B3tSPO-oBBR6fPtGnD2GLP_47Cms8s8GzyNl8ujheXVnNIw0RygTwglxlZYdfChlNf_0MfCwihOeQMUI-hjgCcwxXuMZFUSYrZphQpu1w7VYP5j3dc0nOVnL0YZX_oi62cgeoaWgwn5GjUiif-0AM=,
    keepAlive=true,
    httpHeaders=org.jboss.netty.handler.codec.http.DefaultHttpHeaders@790add3d,
    exEx=null,
    redirectCount=0,
    timeoutsHolder=null,
    inAuth=false,
    statusReceived=false,
    touch=530188604}
INFO - Websocket connection closed, reconnecting...
11:26:13.920 [New I/O worker #1] DEBUG com.ning.http.client.providers.netty.channel.ChannelManager - Closing Channel [id: 0x0e0d06c0, /192.168.99.102:46345 :> mpmulti-6wbl.slack-msgs.com/54.172.207.190:443] 
Run Code Online (Sandbox Code Playgroud)

aut*_*nix 5

在对该问题进行了一些额外的研究并尝试了各种方法之后,我设法解决了这个问题。

似乎#slack API需要定期发送ping消息,以防止断开连接。

在执行计时器代码以每30秒发送ping消息之后,到目前为止,我再也没有遇到此问题。

这是我为了解决此问题而添加的部分代码:

def initRTM(): Unit = {

    h.debug("\nOpening Real Time Messaging socket")

    h.debug("Pinging at 30s intervals")
    val ex = new ScheduledThreadPoolExecutor(1)
    val task = new Runnable {
      def run() = sendPing()
    }
    val f = ex.scheduleAtFixedRate(task, 1, 30, TimeUnit.SECONDS)

    if(!slack.isOpen){
      f.cancel(false)
    }
    [...]
}
Run Code Online (Sandbox Code Playgroud)

RTM API(https://api.slack.com/rtm)并未明确规定必须发送ping消息以保持连接有效,但强烈建议这样做:

客户应该尝试即使在空闲时间也能快速检测到断开连接,以便用户可以轻松分辨断开连接与每个人都安静之间的区别。并非所有的Web浏览器都支持WebSocket ping规范,因此RTM协议也支持ping / pong消息。如果没有其他活动,客户端应每隔几秒钟发送一次ping

实际上,这似乎是维持连接活动的要求。

我希望这在使用#slack RTM API时能帮助其他用户解决类似问题。