2017-09-13 1 views
0

Im Moment entwickle ich eine Art Parser für die Nachrichten des Skypatrol TT8750 + und mein Thread-TCP-Server funktioniert. Das Problem ist, dass es kein guter Ansatz ist, wenn zu viele Geräte gleichzeitig verbunden sind. Ich benutze Jod, aber ich kann keinen Code schreiben, der mir gegeben wurde. Mein Ziel ist es, zuerst eine 33-Byte-Nachricht zu empfangen, um das Gerät zu identifizieren und dann 86-Byte-Nachrichten mit Informationen über das Fahrzeug zu empfangen.AVL-Nachrichten mit Iod behandeln

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 

Und dieser Fehler erscheint auf jeder Nachricht

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 

Auch diese Implementierung nicht die Nachrichten, die ich benötigen bekommt Dies sind die ersten beiden Zeilen, die ich von dieser Implementierung bekam:

0021000a0800000000000120202020202038363332383630323034333433373020 
0021000a08000000000001202020202020383633323836303230343334333730200056000a08100020202020202038363332383630323034333433373020014b0000 

Und das sind die ersten beiden Zeilen von der Gewinde-Implementierung

0021000a0800000000000120202020202038363332383630323034333433373020 
0056000a08100020202020202038363332383630323034333433373020000b00000013090044709bfb8109e400000000001100000000000067eb11090c1512012e970020000000000005000000000005000000000007 
0056000a08100020202020202038363332383630323034333433373020010b00000013090044709bfb8109e400000000001200000000000067eb11090c1512042e970020000000000005000000000005000000000008 
+0

In der Thread-Implementierung scheint die erste Zeile 86 Bytes lang zu sein, nicht die 33 Bytes, die Sie von einer ersten Nachricht erwartet .... die Ausnahme zu beheben (siehe meine Antwort) sollte alle anderen Nachrichten beheben, die verarbeitet werden. – Myst

+0

Das ist, weil ich in meiner Testdatei diese erste Zeile ignoriere, aber es ist die gleiche wie die erste Zeile, die ich in diesem Jod-Server zeige. Danke @Myst –

Antwort

0

Das sieht wie eine Variation des ungeprüften Codes aus, den ich früher bekannt gab.

Es scheint, das Problem ist mit einem Rechtschreibfehler im Code (wahrscheinlich meins?).

Die po += ... sollte

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 

Wieder pos += ... gewesen sein, eine Emulation für die Skypatrol TT8750 + fehlt, kann ich den Code nicht testen. Es sollte jedoch möglich sein, Fehlermeldungen zu verfolgen, um diese Arten von Problemen langsam aufzuspüren.

P.S.

Um von Ausnahmen zu schützen, sollten Sie mit Ruby:

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

dh die on_message Methode könnte wie folgt aussehen:

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 

Auch FYI, Jod ermöglicht es Ihnen, die Anzahl der steuern Prozesse (Arbeiter) und Threads, die Sie verwenden. Einzelheiten finden Sie unter the documentation.

+0

Mein schlechtes für diesen Fehler nicht sehen. Vielen Dank @Myst –

+0

@AndersonAlbertoOchoaEstupia - technisch ist es meine Rechtschreibfehler, so dass ich mich entschuldige. Ich bin glücklich zu helfen. – Myst

+0

Es funktioniert perfekt. Vielen Dank –

Verwandte Themen