alworker:tcp_ipサーバー
文書の過去の版を表示しています。
AlWorker TCP/IPサーバー
require "al_worker_tcp"
TCPサーバーを作成する機能です。SMTPサーバのような、chat式のサーバ機能を実装しています。
サンプル
- tcp_server.rb
require "al_worker_tcp" class TcpServer < AlWorker # イニシャライザでTCPを用意する。 def initialize2() @tcp = Tcp.new( "<any>", 25 ) # リスンアドレス、ポート番号を指定。 @tcp.run( self ) end # helloコマンド # "helo localhost" def tcp_helo( sock, param ) sock.puts "250 hello welcome." return true end # mailコマンド # "mail from: <nobody@example.com>" def tcp_mail( sock, param ) if /^from: ?(.+)$/ =~ param[""] sock.puts "250 Ok" else sock.puts "501 Syntax error." end return true end end server = TcpServer.new( "tcp_server" ) server.daemon()
解説
AlWorkerを継承したクラスに “tcp_” をプレフィックスとして付与したメソッドを定義すると、フレームワークにTCPコマンドとして認識されます。
メソッドには、接続ソケット sock と、パラメータ param が渡されます。
パラメータはJSONパースされ、paramには結果のHashが渡されます。JSONパースできなかった場合は、param[""]にパース前の文字列が入ります。
返り値に trueを指定すると継続してコマンドを受けつけ、falseを指定すると接続を切ります。
デフォルトで、接続を切るためのコマンド、"quit"が定義されています。
定義されていないコマンドが送られた場合、"501 Error Command not implemented." を返します。
同期/非同期
イベントハンドラはデフォルトで同期的に呼び出され、たとえば2つのクライアントから同時にコマンドを受信しても、一つずつ実行します。
非同期にしたい場合は、”tcp_a_” をプレフィックスとして付けます。
def tcp_a_xxxx( sock, param ) # any code return true end
サービスモデル(スレッド/プロセス)
デフォルトで、スレッドモデルで動作します。
接続ごとに別プロセスで動作させる(プロセスモデル)には、以下のように指定します。
@tcp.mode_service = :process
chat以外のプロトコルを使用
chat方式ではないプロトコルを使いたい場合は、Tcpクラスを継承して、_start_service()メソッドをオーバライドします。
すべてのGETリクエストに "It works!" と返すウェブサーバ
class WebServer < AlWorker::Tcp def _start_service( sock ) req = [] while txt = sock.gets txt.chomp! break if txt.empty? req << txt end if !req.empty? && req[0].upcase.start_with?("GET ") sock.puts "HTTP/1.0 200 OK\r\n" sock.puts "Content-Type: text/html\r\n" sock.puts "\r\n" sock.puts "<!DOCTYPE html>\r\n" sock.puts "<title>TESTPAGE</title>\r\n" sock.puts "<p>It works!</p>\r\n" end rescue Exception => ex raise ex if ex.class == SystemExit AlWorker.log( ex ) ensure sock.close if ! sock.closed? end end
alworker/tcp_ipサーバー.1448162688.txt.gz · 最終更新: 2015/11/22 12:24 by 127.0.0.1