2017-09-13 133 views
0

現在我正在爲Skypatrol TT8750 +的消息開發某種解析器,並且我的線程化TCP服務器正在工作。問題在於,如果同時連接很多設備,這不是一個好方法。我正在使用碘,但我不能讓一些代碼給我工作。我的目標是首先收到一條33bytes的信息來識別設備,然後開始接收86bytes的車輛信息。用碘處理AVL消息

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 

並且在一切消息

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 

出現此錯誤也該實現沒有得到我所需要的 這些都是前兩行,我從這個實現了消息:

0021000a0800000000000120202020202038363332383630323034333433373020 
0021000a08000000000001202020202020383633323836303230343334333730200056000a08100020202020202038363332383630323034333433373020014b0000 

這些是線程執行的前兩行

0021000a0800000000000120202020202038363332383630323034333433373020 
0056000a08100020202020202038363332383630323034333433373020000b00000013090044709bfb8109e400000000001100000000000067eb11090c1512012e970020000000000005000000000005000000000007 
0056000a08100020202020202038363332383630323034333433373020010b00000013090044709bfb8109e400000000001200000000000067eb11090c1512042e970020000000000005000000000005000000000008 
+0

在線程實現中,第一行似乎是86字節長,而不是第一個消息所期望的33字節....修復異常(請參閱我的答案)應該修復正在處理的其他消息。 – Myst

+0

這是因爲我在我的測試文件中忽略了第一行,但它與我在該碘服務器中顯示的第一行相同。謝謝@Myst –

回答

0

這看起來像我之前發佈的未經測試的代碼的變體。

看來問題出在代碼中的拼寫錯誤(可能是我的?)。

po += ...應該已經​​

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 +仿真,我無法測試的代碼。但應該可以遵循錯誤消息來慢慢追蹤這些類型的問題。

P.S.

要從例外保護,可以考慮使用Ruby的:

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

on_message方法可能是這樣的:

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 

此外,僅供參考,碘,可以控制數量進程(工作人員)和你正在使用的線程。詳情請參閱the documentation

+0

我的不好看不到那個錯誤。非常感謝你@Myst –

+0

@AndersonAlbertoOchoaEstupia - 從技術上講,這是我的拼寫錯誤,所以這是我的道歉。我很樂意提供幫助。 – Myst

+0

它完美的作品。謝謝 –