用碘处理AVL消息 [英] handle AVL messages with iodine

查看:96
本文介绍了用碘处理AVL消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我正在为Skypatrol TT8750 +的消息开发某种解析器,并且我的线程TCP服务器正在运行.问题是,如果同时连接多个设备,这不是一个好方法.我正在使用碘,但无法使提供给我的某些代码工作.我的目标是首先接收33字节的消息来识别设备,然后开始接收86字节的消息以及车辆信息.

Right now I'm developing a some sort of parser for the messages of the Skypatrol TT8750+ and my threaded TCP server is working. The problem is that it isn't a good approach if there are to many devices connected at the same time. I'm using iodine but I can't make work some code that was given to me. My goal is to receive first a 33bytes message to identify the device and then start to receive 86bytes messages with information of the vehicle.

require 'iodine'

# define the protocol for our service
class TT8750plus
  @timeout = 10
  def on_open
    puts "New Connection Accepted."
    # this file is just for testing purposes.
    t = Time.now.strftime("%d-%m-%Y %H%M")
    file_name = t + '.txt'
    @out_file = File.new(file_name, "w+")

    # a rolling buffer for fragmented messages
    @expecting = 33
    @msg = ""
  end

  def on_message buffer
    length = buffer.length
    pos = 0
    while length >= @expecting
      @msg << (buffer[pos, @expecting])
      @out_file.puts(@msg.unpack('H*')[0])
      length -= @expecting
      po += @expecting
      @expecting = 86
      @msg.clear
    end
    if(length > 0)
      @msg << (buffer[pos, length])
      @expecting = 86 - length
    end
    puts @msg
  end

  def on_close
    @out_file.close
  end
end
# create the service instance
Iodine.listen 12050, TT8750plus
# start the service
Iodine.start

此错误出现在每条消息上

And this error appears on every message

New Connection Accepted.
Iodine caught an unprotected exception - NoMethodError: undefined method `+' for nil:NilClass
iodineServer.rb:26:in `on_message'
iodineServer.rb:1:in `on_data'Iodine caught an unprotected exception - NoMethodError: undefined method `+' for nil:NilClass

这个实现也没有得到我需要的消息 这是我从此实现中获得的前两行:

Also this implementation doesn't get the messages I need These are the first two lines that I got from this implementation:

0021000a0800000000000120202020202038363332383630323034333433373020
0021000a08000000000001202020202020383633323836303230343334333730200056000a08100020202020202038363332383630323034333433373020014b0000

这是线程实现的前两行

0021000a0800000000000120202020202038363332383630323034333433373020
0056000a08100020202020202038363332383630323034333433373020000b00000013090044709bfb8109e400000000001100000000000067eb11090c1512012e970020000000000005000000000005000000000007 
0056000a08100020202020202038363332383630323034333433373020010b00000013090044709bfb8109e400000000001200000000000067eb11090c1512042e970020000000000005000000000005000000000008

推荐答案

这看起来像是我之前发布的未经测试的代码的变体.

This looks like a variation of the untested code I posted earlier.

问题似乎出在代码中的拼写错误(可能是我的?).

It seems the issue is with a spelling mistake in the code (probably mine?).

po += ...应该是pos += ...

require 'iodine'

# define the protocol for our service
class TT8750plus
  @timeout = 10
  def on_open
    puts "New Connection Accepted."
    # this file is just for testing purposes.
    t = Time.now.strftime("%d-%m-%Y %H%M")
    file_name = t + '.txt'
    @out_file = File.new(file_name, "w+")

    # a rolling buffer for fragmented messages
    @expecting = 33
    @msg = ""
  end

  def on_message buffer
    length = buffer.length
    pos = 0
    while length >= @expecting
      @msg << (buffer[pos, @expecting])
      @out_file.puts(@msg.unpack('H*')[0])
      length -= @expecting
      pos += @expecting # the spelling mistake was here
      @expecting = 86
      puts "wrote:", @msg
      @msg.clear
    end
    if(length > 0)
      @msg << (buffer[pos, length])
      @expecting = 86 - length
    end
    puts("Waiting for more data:", @msg) unless @msg.empty?
  end

  def on_close
    @out_file.close
  end
end
# create the service instance
Iodine.listen 12050, TT8750plus
# start the service
Iodine.start

同样,由于缺乏对Skypatrol TT8750 +的仿真,我无法测试代码.但是应该可以遵循错误消息来缓慢跟踪这些类型的问题.

Again, lacking an emulation for the Skypatrol TT8750+, I can't test the code. But it should be possible to follow error messages to slowly track down these types of issues.

PS

为了防止异常,请考虑使用Ruby:

To protect from exceptions, consider using Ruby's:

begin
    # code
rescue => e
    # oops something happened. i.e.
    puts e.message, e.backtrace
end

on_message方法可能看起来像这样:

i.e., the on_message method might look like this:

  def on_message buffer
   begin
    length = buffer.length
    pos = 0
    while length >= @expecting
      @msg << (buffer[pos, @expecting])
      @out_file.puts(@msg.unpack('H*')[0])
      length -= @expecting
      pos += @expecting # the spelling mistake was here
      @expecting = 86
      @msg.clear
    end
    if(length > 0)
      @msg << (buffer[pos, length])
      @expecting = 86 - length
    end
    puts @msg unless @msg.empty? # print leftovers for testing...?
   rescue => e
     # oops something happened. React
     puts e.message, e.backtrace
   end
  end

此外,仅供参考,碘使您可以控制正在使用的进程(工人)和线程的数量.有关详细信息,请参见文档.

Also, FYI, iodine allows you to control the number of processes (workers) and threads you'r using. See the documentation for details.

这篇关于用碘处理AVL消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆