内容へ移動
alone-doc
ユーザ用ツール
ログイン
サイト用ツール
検索
ツール
文書の表示
バックリンク
メディアマネージャー
サイトマップ
ログイン
>
メディアマネージャー
サイトマップ
現在位置:
start
»
alworker
»
tcp_ipサーバー
トレース:
alworker:tcp_ipサーバー
この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。
====== AlWorker TCP/IPサーバー ====== require "al_worker_tcp" ---- TCPサーバーを作成する機能です。SMTPサーバのような、chat式のサーバ機能を実装しています。 {{:alworker:tcp_explain1.png?nolink|}} ====== サンプル ====== サーバー <file ruby tcp_server.rb> require "al_worker_tcp" class TcpServer < AlWorker # イニシャライザでTCPを用意する。 def initialize2() @tcp = Tcp.new( "<any>", 10025 ) # リスンアドレス、ポート番号を指定。 @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.parse_option() server.daemon() </file> クライアント(以下の例は、Ruby基本機能のみ使用した例で、Aloneライブラリは使わず実装しています) <file ruby tcp_client.rb> require "socket" sock = TCPSocket.open("localhost", 10025) puts 'SEND "helo"' sock.puts "helo" puts 'RECEIVE ' + sock.gets puts 'SEND "quit"' sock.puts "quit" puts 'RECEIVE ' + sock.gets sock.close </file> ===== 実行結果 ===== <code> % ruby tcp_client.rb SEND "helo" RECEIVE 250 hello welcome. SEND "quit" RECEIVE 200 OK quit. </code> ===== 解説 ===== AlWorkerを継承したクラスに “tcp_” をプレフィックスとして付与したメソッドを定義すると、フレームワークにTCPコマンドとして認識されます。\\ メソッドには、接続ソケット sock と、パラメータ param が渡されます。\\ パラメータはJSONパースされ、paramには結果のHashが渡されます。JSONパースできなかった場合は、param[""]にパース前の文字列が入ります。\\ 返り値に trueを指定すると継続してコマンドを受けつけ、falseを指定すると接続を切ります。\\ デフォルトで、接続を切るためのコマンド、"quit"が定義されています。\\ 定義されていないコマンドが送られた場合、"501 Error Command not implemented." を返します。\\ ====== 同期/非同期 ====== イベントハンドラはデフォルトで同期的に呼び出され、たとえば2つのクライアントから同時にコマンドを受信しても、一つずつ実行します。\\ 非同期にしたい場合は、”tcp_a_” をプレフィックスとして付けます。 <code ruby> def tcp_a_xxxx( sock, param ) # any code return true end </code> ====== バイナリの送受信 ====== Chatプロトコルでは、テキストの送受信のみ想定しており、エンコーディングはデフォルトで UTF-8 です。\\ バイナリの送受信が必要な場合は、以下のようにエンコーディングを変更します。 <code ruby> @tcp.set_encoding(Encoding::ASCII_8BIT) </code> ====== サービスモデル(スレッド/プロセス) ====== デフォルトで、スレッドモデルで動作します。\\ 接続ごとに別プロセスで動作させる(プロセスモデル)には、以下のように指定します。 <code ruby> @tcp.mode_service = :process </code> ====== chat以外のプロトコルを使用 ====== chat方式ではないプロトコルを使いたい場合は、AlWorker::Tcpクラスを継承して、start_service()メソッドをオーバライドします。 すべてのGETリクエストに "It works!" と返すウェブサーバ <file ruby web_server.rb> require "al_worker_tcp" 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 end end class TcpServer < AlWorker def initialize2() log.level = Logger::DEBUG @tcp = WebServer.new("<any>", 3000) # リスンアドレス、ポート番号を指定。 @tcp.run( self ) end end server = TcpServer.new("web_server") server.daemon() </file>
alworker/tcp_ipサーバー.txt
· 最終更新:
2023/08/19 12:06
by
hirohito
ページ用ツール
文書の表示
バックリンク
文書の先頭へ