首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正确使用套接字和/或Celluloid::IO

正确使用套接字和/或Celluloid::IO
EN

Stack Overflow用户
提问于 2014-10-09 14:09:37
回答 1查看 526关注 0票数 3

我有一台Pinoccio microcontroller (太棒了,试试吧)。微控制器打开连接到它的服务器的套接字。我正在一个Ruby应用程序中编写TCP Socket服务器,在该应用程序中我将使用Celluloid::IO。作为我的指南,我将在Node中跟踪这个名为pinoccio-server的实现

我写了一些测试代码,试图与匹诺曹单片机通信。我可以毫不费力地从其中读取数据,但是当我将数据写回套接字时,我永远不会得到我期望的行为。这是代码,谁能告诉我我是误用了Celluloid::IO还是sockets?

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

EN

回答 1

Stack Overflow用户

发布于 2015-08-27 19:05:13

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

下面是新的要点:

代码语言:javascript
复制
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. 不再在
  3. 中启动服务器,并在执行元与新的reinstantiated.
  4. Become兼容后重新启动服务器静默关闭位于end.
  5. Forcefully,的服务器静默关闭位于disconnect.
  6. Avoid的套接字复制由itself.
  7. Avoid使用主机名启动的关闭
  8. ,主机名通常不在那里。

numeric address.

  1. Catch写操作导致的错误类型,并向您显示套接字的reason.
  2. Closure将始终发生,而不管套接字如何终止。

你最初开始的代码应该已经工作了,或者至少它应该给你一个清楚的原因为什么它不工作。从0.17.0开始,上面的代码与Celluloid兼容,对于新的Celluloid::IO也是如此……如果您有任何进一步的问题,请包括具体的错误。

注意:您可能需要检测到服务器崩溃了,并且仍然保持打开您期望可用的端口,而这并未包含在示例中...但在Celluloid::IO测试套件中给出了一个这样的示例:

https://github.com/celluloid/celluloid-io/commit/dc352d5a4d86684ad7cc8bc3b348ee7e9d92f8b3#L47中的

  • In assign_port
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26271456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档