Rubyでサーバを作ってクライアントにデータを配信 vol.5

vol.4のプログラムはclientsにひとつずつ配信しています。 一瞬で終わるならいいのですが、ネットワークなんて遅延しまくりなので、 あまりよろしくありません。一度に配信処理をしたいものです。 試しに2秒遅延を入れてみると、こうなります。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

sockets = [gate, STDIN]
clients = []
loop do
  r_sockets = IO.select(sockets+clients)[0]
  r_sockets.each do |socket|
    case socket
    when STDIN
      str = socket.gets
      clients.each do |client|
        client.puts str.upcase
        sleep 2
      end
    when TCPServer
      client = socket.accept
      clients << client
      p clients
    when TCPSocket
      unless socket.eof?
        str=socket.gets
        socket.puts str.upcase
      else
        socket.close
        clients.delete(socket)
        p clients
      end
    end
  end
end

gate.close

このくらいレスポンスが悪いと、ああ、なんとかしなきゃならないなと思いますね。


multisend04 - YouTube

Rubyでサーバを作ってクライアントにデータを配信 vol.4

スレッドなどでそれぞれ待ち受けるという手もありますが、 IOの入出力を待つ手段としては一般的ではないようです。 IOの動きを監視して待ち受け、動きがあったら場合分けをして 処理をするのが一般的なようです。 これをReactorパターンといいます。 IO.selectで配列を引数に入れると、 引数で入れたものに動きがあるまで待ち続けます。 動きがあると、次のステップに進むので、そこで場合分けをして処理をします。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

sockets = [gate, STDIN]
clients = []
loop do
  r_sockets = IO.select(sockets+clients)[0]
  r_sockets.each do |socket|
    case socket
    when STDIN
      str = socket.gets
      clients.each do |client|
        client.puts str.upcase
      end
    when TCPServer
      client = socket.accept
      clients << client
      p clients
    when TCPSocket
      unless socket.eof?
        str=socket.gets
        socket.puts str.upcase
      else
        socket.close
        clients.delete(socket)
        p clients
      end
    end
  end
end

gate.close

いくつも同時に接続して、配信可能です。 f:id:xibbar:20150817141657p:plain

Rubyでサーバを作ってクライアントにデータを配信 vol.3

forkはダメです。forkは別プロセスを立ち上げるので、メモリの共有ができません。 なので、同じデータの一斉配信には向いていません。プロセス間通信とか仕組みが面倒です。

ちゃんと動かないプログラムをとりあえず書いてみました。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

clients = []
pid=Process.pid
fork
if pid == Process.pid
  loop do
    clients << gate.accept
    p clients
  end
else
  while msg = STDIN.gets
    p clients
    clients.each do |client|
      if client.closed?
        clients.delete client
      else
        begin
          client.puts msg.upcase
        rescue

        end
      end
    end
  end
end
gate.close

いきなりforkして、接続待ちと書き出しを別々のプロセスでやっているという 意味のないプログラムです。

Rubyでサーバを作ってクライアントにデータを配信 vol.2

vol.1 のサーバだと、1対1の通信しかできません。これだとサーバ&クライアント型の プログラムとは言い難いので、サーバ1台に対し、クライアント複数台で作ってみます。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

clients = []
s=Thread.new do
  loop do
    clients << gate.accept
    p clients
  end
end

while msg = STDIN.gets
  p clients
  clients.each do |client|
    if client.closed?
      clients.delete client
    else
      begin
        client.puts msg.upcase
      rescue

      end
    end
  end
end

gate.close

s.join

これだと複数接続できます。接続待ちをするループをThreadにして放置して、 他方でサーバの標準入力待ちを作っています。 接続を切られてしまった場合の処理はどうすればいいのかは よくわかっていません。とりあえず、closed?が返ったり書き込もうとして 例外が返った場合の処理だけしています。 クライアント切っただけではclosed?がtrueにならないのに、 書き込みはできずに例外が返ったりして、よくわかりません。

Rubyでサーバを作ってクライアントにデータを配信 vol.1

これはRubyで作ったソケットサーバに接続してきたクライアントにデータを配信するための勉強上の知見です。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

sock = gate.accept
gate.close

while msg = STDIN.gets
    sock.puts msg.upcase
end
sock.close

サーバを立ち上げる

% ruby multisend00.rb 9999

クライアントはワンライナーで。

ruby -rsocket -e 's=TCPSocket.new("localhost",9999);while a=s.gets;puts a end'

サーバ上で、「abc」と入力してエンターを押すと、 クライアント画面にABCと大文字になって出てくる。 f:id:xibbar:20150814160223p:plain

懐中電灯作った

息子がキャンプに持っていく懐中電灯買って欲しいという。 よし!つくろう。と思って作ったのがこちら。


LED Light - YouTube

スズメッキ線を殆ど使わずにはんだだけで結線しています。 基板は秋月で売っているもので、ブレッドボードのような 配線になっていて、縦と横のホールが大分つながっています。

ただのお遊びです。

ラビックスは14期目に入りました

創業してから13年も経営してしまいました

なんだかあっという間の1年でした。移転して慣れるまで時間がかかりました。 こうして挨拶を書けるのも、 ラビックスを続けようとしてくれている社員とみなさまのお陰です。 一回り以上してしまったので、これからはいかに続けるかと、 いかに安定して成長するかでしょう。

ちょっとずついろいろできることが増えてきました

娘が4歳になったので、ちょっとずつ手がかからなくなってきました。 病気も熱を出した時以外は割りと安定している感じです。 息子は10歳です。もうちょっとで中学生か〜とか思います。早い。 そして、大丈夫か??とか思います。

新しい業務

新しいサービスを開始します。もうちょっとしたらリリースします。 新しいと言っても既存のe-安否に付随させるサービスです。 そっからスタートです。

藤岡が思う復興

福島ですし、復興に関することはあらゆることで耳に入りますし、 社会の一員を担う以上、復興は無視というわけにはいきません。 でも、ボランティア活動をする人がいたり、募金活動をする人もいます。 芸術活動をする人もいます。 原発への反対活動をする人もおそらく当事者は復興の活動の一部だと思っているに違いありません。 私には自分自身が思う復興活動というものがあります。 それは、ビジネスを大きくすることです。 私は復興というものはビジネス以外ありえないと思っています。 経済を中心に循環しない限り寂れるだけだと思っています。 雇用を少しでも生むというのが大切です。 それに微力ながら役に立てればいいと思っています。

最後に

今期もラビックスは新しいビジネスをもって社会に貢献します。 みなさま今後共よろしくお願いします。

去年と同じことを言っていますが、 # 福島市中心部で、家政婦さんをやれる人がいたら教えて下さい。