Использование Ruby для соединения с несколькими интерфейсами ввода-вывода IP, Netiom - PullRequest
1 голос
/ 21 февраля 2011

Я пытаюсь создать приложение, написанное на ruby, которое взаимодействует с несколькими интерфейсами ввода / вывода через TCP / IP. Интерфейс ввода-вывода, который я использую, называется NETIOM. Интерфейс имеет 16 цифровых входов и 16 цифровых выходов.

Как мне:

  • обрабатывать несколько соединений? Я использую массив?
  • отправить сообщение через одно соединение и посмотреть его ответ?
  • «сделать что-то», когда вход срабатывает? Мне нужно было бы определить, на каком входе и интерфейсе он был запущен.

Этот код работает для одного устройства Netiom, а также может обнаруживать нажатия входов, но код выходит через некоторое время. Я экспериментировал с классами и массивами, но никуда не попал.

require 'socket'
server = TCPServer.open(3012)
@socket = server.accept
@socket.puts "SEND\r\n"
while line = @socket.gets
  puts line.chop
end

этот код возвращает:

Цифровые входы 1-8: 11111111
Цифровые входы 9-16: 11111111
Цифровые выходы 1-8: 00000000
Цифровые выходы 9-16: 00000000

Поскольку клиент действует определенным образом, я записал некоторую информацию о том, как он работает. Также есть ссылка на руководство в формате pdf (см. 9-ю страницу). http://www.phaedrusltd.com/Download/NETIOM%20Instructions.pdf

Я ценю любую помощь, которую вы можете оказать мне, и большое спасибо за ваше время.

При программировании интерфейса вы можете указать IP-адрес и порт сервера, с которым вы хотите общаться, это будет наш сервер ruby. По умолчанию интерфейс пытается подключиться к серверу каждые 10 секунд, пока сервер, наконец, не примет. Как только сервер примет соединение, он должен отправить сообщение «ОТПРАВИТЬ», и интерфейс затем вернет некоторые данные со статусом всех входов и выходов, показанным ниже. Если и когда мы захотим закрыть соединение, мы отправим сообщение «ЗАКРЫТЬ».

Возвращаемые данные:

Digital inputs 1-8 : 11111111
Digital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000

Если один из 16 входов нажат при наличии соединения, он отправляет те же данные, что и раньше, но меняет этот конкретный вход на «0»

Digital inputs 1-8 : 01111111 // вход 1 сработал
Digital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000

Когда кнопка отпущена или отпущена, файл снова отправляется, но теперь ввод возвращается в нормальное состояние.

Digital inputs 1-8 : 11111111 // вход 1 возвращается в нормальное состояние.
Digital inputs 9-16: 11111111
Digital outputs 1-8 : 00000000
Digital outputs 9-16: 00000000

Если я хочу включить выход 8, я отправляю A08, а чтобы выключить его, я отправляю B08. Я могу переключить выход с помощью T08.

1 Ответ

1 голос
/ 21 февраля 2011

Используйте Thread для работы с несколькими подключениями, используйте TCP-сервер для управления TCP и NETIOM manager для работы с вашими устройствами.

Что-то в этом роде (не проверено, это копия / прошлое из моих работ)):

require 'socket'
require 'thread'
require 'timeout' 


class TcpServer
    def initialize(iOServeur,port) 
        @port=port
        @ioserver=iOServeur
        @th=[]
        @server = TCPServer.new('0.0.0.0', @port)
        @server.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
        Thread.new do
            begin
              while (session = @server.accept)
                Thread.new(session) do |sess|
                begin
                   @th[Thread.current]=Time.now
                   ip=@session.peeraddr.last
                   @ioserveur.connection(ip)
                   request(ip,sess) 
                ensure
                    @ioserveur.deconnection(ip)
                    sess.close rescue nil
                    @th.delete(Thread.current)
                end
                end
              end
            rescue
              error($!.to_s)
            end
        end
    end
    def request(ip,sock)
        while (str=sock.read)
          ret=@ioServer.received(ip,str)
          if ret 
             sock.write(ret) if String===ret && ret.length>0 
          else
             sock.close raise nil
             return;
          end

        end
    end
end

class IoServer
    def initialize() end
    def connection(ip) end
    def deconnection(ip) end
    def received(ip,str) return "" end
end

Thread.abort_on_exception = true if $DEBUG
BasicSocket.do_not_reverse_lookup = true
ios=IoServer.new
TcpServer.new(ios,8080)
gets # !!
...