3

私はPinoccio マイクロコントローラーを持っています(絶対に素晴らしいので試してみてください)。マイクロコントローラーは、サーバーへのソケットを開きます。私はCelluloid::IOを使用する Ruby アプリケーションでその TCP ソケット サーバーを作成しています。私のガイドとして、私はpinoccio-serverと呼ばれるノードでのこの実装に従っています

Pinoccio マイクロコントローラとの通信を試みるために、いくつかのテスト コードを作成しました。問題なく読み取ることができますが、データをソケットに書き戻すと、予期した動作が得られません。これがコードです。私がCelluloid::IOまたはソケットを誤用しているかどうか教えてもらえますか?

https://gist.github.com/roder/ab211f2f58ad6c90a3a9

4

1 に答える 1

0

この質問の時点で、構文は正しかった。しかし、今ではそうではありません0.17.0...Celluloidしかし、それは答えではありません。それは単なる序文です。私はあなたの要点をフォークして編集しました:

https://gist.github.com/digitalextremist/7dc74b03587cd4b3b7dd

新しい要点は次のとおりです。

require 'celluloid/current'
require 'celluloid/io'
require 'json'

class TestServer
  include Celluloid::IO
  finalizer :shutdown

  def initialize(host, port)
    puts "*** Starting echo server on #{host}:#{port}"

    # Since we included Celluloid::IO, we're actually making a
    # Celluloid::IO::TCPServer here
    @server = TCPServer.new(host, port)
  end

  def shutdown
    @server.close rescue nil
  end

  def run
    loop {
      async.handle_connection(@server.accept)
    }
  end

  def handle_connection(socket)
    addr = *socket.peeraddr
    puts "*** Received connection from #{addr[3]}:#{addr[1]}"

    # This is just a test, followed this format:
    #  https://github.com/soldair/pinoccio-server/blob/master/troop.js#L163
    cmd = {
      :type => "command",
      :to => 1,
      :timeout => 10000,
      :command => "led.on"
    }
    json_cmd = "#{cmd.to_json}\n"
    socket.write json_cmd # The light never turns on. Why?
    puts json_cmd

    loop {
      puts socket.readpartial(4096)
    }
  rescue EOFError
    puts "*** #{addr[3]}:#{addr[1]} disconnected"
  rescue => ex
    echo "Trouble with socket: [#{ex.class}] #{ex.message}"
  ensure
    socket.close rescue nil
  end
end

TestServer.supervise(as: :test_server, args: ["0.0.0.0", 1234])
#de Not needed. Killed by Celluloid.shutdown already...
#de trap("INT") { supervisor.terminate; exit }

#de Avoid starting the server in the constructor, then sleeping.
#de Could end up with a race condition, and/or botch instantiation.
#de But with that being said, you need to detect crashes... so:
loop {
  begin
    Celluloid[:test_server].run
  rescue => ex
    echo "Trouble with supervised server: [#{ex.class}] #{ex.message}"
    echo "Waiting 1.26 seconds for actor to be reinstantiated."
    sleep 1.26
  end
}

主な変更点:

  1. 最初に呼び出しCelluloidて、適切にスピンアップさせます。
  2. でサーバーを起動しなくなりましたinitialize
  3. サーバーの停止をキャッチし、アクターが再インスタンス化された後にサーバーを再起動します。
  4. 新しい API に準拠します。
  5. 最後にサーバーを強制的に静かに閉じます。
  6. 切断時にソケットを強制的に静かに閉じます。
  7. すでに開始されているシャットダウンを複製することは避けてくださいCelluloid
  8. 多くの場合、そこにないホスト名を使用しないでください。数値アドレスを表示します。
  9. 書き込みによって発生するエラーのタイプをキャッチし、その理由を示します。
  10. ソケットの終了方法に関係なく、ソケットの閉鎖は常に発生します。

最初に開始したコードは機能するはずでした。または、少なくとも、機能しなかった明確な理由が示されているはずです。上記のコードは現在、新しいものと互換性がありCelluloidます...さらに問題がある場合は、特定のエラーを含めてください。0.17.0Celluloid::IO

注:サーバーがクラッシュしたことを検出する必要がある可能性があり、使用できると予想されるポートをまだ開いたままにしており、それは例には含まれていません...しかし、その例はCelluloid::IOテストスイートに示されています:

于 2015-08-27T11:05:13.323 に答える