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
いくつも同時に接続して、配信可能です。
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と大文字になって出てくる。
懐中電灯作った
息子がキャンプに持っていく懐中電灯買って欲しいという。 よし!つくろう。と思って作ったのがこちら。
スズメッキ線を殆ど使わずにはんだだけで結線しています。 基板は秋月で売っているもので、ブレッドボードのような 配線になっていて、縦と横のホールが大分つながっています。
ただのお遊びです。
ラビックスは14期目に入りました
創業してから13年も経営してしまいました
なんだかあっという間の1年でした。移転して慣れるまで時間がかかりました。 こうして挨拶を書けるのも、 ラビックスを続けようとしてくれている社員とみなさまのお陰です。 一回り以上してしまったので、これからはいかに続けるかと、 いかに安定して成長するかでしょう。
ちょっとずついろいろできることが増えてきました
娘が4歳になったので、ちょっとずつ手がかからなくなってきました。 病気も熱を出した時以外は割りと安定している感じです。 息子は10歳です。もうちょっとで中学生か〜とか思います。早い。 そして、大丈夫か??とか思います。
新しい業務
新しいサービスを開始します。もうちょっとしたらリリースします。 新しいと言っても既存のe-安否に付随させるサービスです。 そっからスタートです。
藤岡が思う復興
福島ですし、復興に関することはあらゆることで耳に入りますし、 社会の一員を担う以上、復興は無視というわけにはいきません。 でも、ボランティア活動をする人がいたり、募金活動をする人もいます。 芸術活動をする人もいます。 原発への反対活動をする人もおそらく当事者は復興の活動の一部だと思っているに違いありません。 私には自分自身が思う復興活動というものがあります。 それは、ビジネスを大きくすることです。 私は復興というものはビジネス以外ありえないと思っています。 経済を中心に循環しない限り寂れるだけだと思っています。 雇用を少しでも生むというのが大切です。 それに微力ながら役に立てればいいと思っています。
最後に
今期もラビックスは新しいビジネスをもって社会に貢献します。 みなさま今後共よろしくお願いします。
去年と同じことを言っていますが、 # 福島市中心部で、家政婦さんをやれる人がいたら教えて下さい。
さくらクラウドとRTX810でVPNを使ってLAN同士を接続する
仕事で必要なので、社内でつなげようと動作を検証していましたが、 やっと動作したので、やり方を報告します。
基本的には サイト間VPN設定 | さくらのクラウド ドキュメント に載っているとおりです。
注意としては、RTX810ではIPsec IDはローカルIPアドレスになります。 記事で言うと、*3で注意書きがあります。
また、PPPoEでプロバイダとつないでいたりすると、グローバルIPアドレスに IP Masqueradeの設定が入っているので、LAN側にNATでIP Secのパケットを 引きこまなければなりません。うちはネットワーク型のPPPoEですので、 記事のとおりの設定+以下の設定を入れました。
nat descriptor masquerade static 1000 13 10.0.0.1 udp 500 nat descriptor masquerade static 1000 14 10.0.0.1 esp nat descriptor masquerade static 1000 15 10.0.0.1 udp 4500
これはRTX810のグローバルIPアドレスのNAT設定への追記になります。 うちのPPPoEでネットワーク型接続をしているルーターと さくらクラウドのVPCとの接続設定のサンプルを載せておきます。 参考までにどうぞ。
ip route default gateway pp 1 ip route 172.16.0.0/16 gateway tunnel 1 vlan port mapping lan1.1 vlan1 vlan port mapping lan1.2 vlan2 vlan port mapping lan1.3 vlan3 vlan port mapping lan1.4 vlan4 lan type lan1 port-based-option=divide-network ip vlan1 address 10.0.0.1/24 ip vlan1 secure filter in 200099 ip vlan1 secure filter out 200099 ip vlan2 address 198.51.100.124/27 ip vlan2 nat descriptor 1000 ip vlan2 secure filter in 200099 ip vlan2 secure filter out 200099 provider type isdn-network provider vlan1 name LAN: provider lan2 name PPPoE/0/3/5/0/0:Provider pp select 1 pp name PRV/1/3/5/0/0:Provider pp keepalive interval 30 retry-interval=30 count=12 pppoe use lan2 pppoe auto disconnect off pp auth accept pap chap pp auth myname username password ppp lcp mru on 1454 ppp ipcp msext on ppp ccp type none ip pp secure filter in 200099 ip pp secure filter out 200099 ip pp nat descriptor 1000 pp enable 1 provider set 1 Provider provider dns server pp 1 1 provider select 1 tunnel select 1 ipsec tunnel 101 ipsec sa policy 101 1 esp aes-cbc sha-hmac ipsec ike always-on 1 on ipsec ike encryption 1 aes-cbc ipsec ike group 1 modp1024 ipsec ike hash 1 sha ipsec ike keepalive log 1 off ipsec ike keepalive use 1 on dpd 15 2 ipsec ike local address 1 10.0.0.1 ipsec ike local id 1 10.0.0.1 ipsec ike pfs 1 on ipsec ike pre-shared-key 1 text test12345 ipsec ike remote address 1 203.0.113.180 ipsec ike remote id 1 203.0.113.180 ipsec auto refresh 1 on ip tunnel mtu 1280 ip tunnel tcp mss limit auto tunnel enable 1 ip filter 200099 pass * * * * * nat descriptor type 1000 masquerade nat descriptor address outer 1000 198.51.100.124 nat descriptor address inner 1000 10.0.0.1-10.0.0.254 nat descriptor masquerade static 1000 13 10.0.0.1 udp 500 nat descriptor masquerade static 1000 14 10.0.0.1 esp nat descriptor masquerade static 1000 15 10.0.0.1 udp 4500 ipsec auto refresh on syslog notice on syslog debug on
手元の設定をかなり削って、IPアドレスやら設定をかなり変更したので、 もしもどこか間違っていたらごめんなさい。