2017-09-13 8 views
0

En ce moment je développe une sorte d'analyseur pour les messages du Skypatrol TT8750 + et mon serveur TCP threadé fonctionne. Le problème est que ce n'est pas une bonne approche s'il y a plusieurs périphériques connectés en même temps. J'utilise de l'iode mais je n'arrive pas à faire fonctionner du code qui m'a été donné. Mon objectif est de recevoir d'abord un message de 33 octets pour identifier l'appareil, puis commencer à recevoir des messages 86 octets avec des informations sur le véhicule.gérer les messages AVL avec l'iode

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 

Et cette erreur apparaît sur chaque 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 

De plus, cette mise en œuvre ne reçoit pas les messages que je besoin Ce sont les deux premières lignes que j'ai obtenu de cette mise en œuvre:

0021000a0800000000000120202020202038363332383630323034333433373020 
0021000a08000000000001202020202020383633323836303230343334333730200056000a08100020202020202038363332383630323034333433373020014b0000 

Et ce sont les deux premières lignes de l'implémentation filetée

0021000a0800000000000120202020202038363332383630323034333433373020 
0056000a08100020202020202038363332383630323034333433373020000b00000013090044709bfb8109e400000000001100000000000067eb11090c1512012e970020000000000005000000000005000000000007 
0056000a08100020202020202038363332383630323034333433373020010b00000013090044709bfb8109e400000000001200000000000067eb11090c1512042e970020000000000005000000000005000000000008 
+0

Dans l'implémentation par threads, la première ligne semble avoir une longueur de 86 octets, pas les 33 octets que vous attendiez d'un premier message .... La correction de l'exception (voir ma réponse) devrait résoudre tous les autres messages traités. – Myst

+0

C'est parce que j'ignore dans mon fichier de test cette première ligne mais c'est la même que la première ligne que je montre dans ce serveur d'iode. Merci @Myst –

Répondre

0

Cela ressemble à une variation du code non testé que j'ai posté plus tôt.

Il semble que le problème est dû à une faute d'orthographe dans le code (probablement le mien?).

Le po += ... aurait dû être 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 

Encore une fois, manque une émulation pour le Skypatrol TT8750 +, je ne peux pas tester le code. Mais il devrait être possible de suivre les messages d'erreur pour trouver lentement ces types de problèmes.

P.S.

Pour protéger des exceptions, pensez à utiliser Ruby:

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

-à-dire, la méthode on_message pourrait ressembler à ceci:

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 

En outre, votre information, l'iode permet de contrôler le nombre de processus (travailleurs) et threads que vous utilisez. Voir the documentation pour plus de détails.

+0

Mon mauvais pour ne pas voir cette erreur. Merci beaucoup @Myst –

+0

@AndersonAlbertoOchoaEstupia - techniquement, c'est mon erreur d'orthographe, alors c'est moi qui s'excuse. Je suis heureux d'aider. – Myst

+0

Cela fonctionne parfaitement. Je vous remercie –