class IPCam::WebSocket
Attributes
Public Class Methods
イベント情報の一斉送信
@param [String] name イベント名 @param [Array] args イベントで通知する引数
# File lib/ipcam/websock.rb, line 93 def broadcast(name, *args) sync {session_list.each {|s| s.notify(name, *args)}} end
セッションオブジェクトからのセッション削除
@param [Socket] sock
セッションオブジェクトを特定するためのソケットオブジェクト
# File lib/ipcam/websock.rb, line 74 def bye(sock) sync { session_list.reject! { |s| if s === sock s.finish true else false end } } end
セッションオブジェクトのイニシャライザ
@param [IPCam] app アプリケーション本体のインスタンス @param [Socket] sock Socketインスタンス
# File lib/ipcam/websock.rb, line 185 def initialize(app, sock) @app = app @sock = sock @allow = [] peer = Socket.unpack_sockaddr_in(sock.get_peername) @addr = peer[1] @port = peer[0] end
WebSocket制御の開始
# File lib/ipcam/websock.rb, line 116 def start(app) EM.defer { @app = app sleep 1 until EM.reactor_running? $logger.info("websock") {"started (#{bind_url()})"} opts = { :host => $bind_addr, :port => $ws_port, :secure => $use_ssl, :tls_options => { :private_key_file => $ssl_key, :cert_chain_file => $ssl_cert } } EM::WebSocket.start(opts) { |sock| peer = Socket.unpack_sockaddr_in(sock.get_peername) addr = peer[1] port = peer[0] serv = join(sock) sock.set_sock_opt(Socket::Constants::SOL_SOCKET, Socket::SO_KEEPALIVE, true) sock.set_sock_opt(Socket::IPPROTO_TCP, Socket::TCP_QUICKACK, true) sock.set_sock_opt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, false) sock.onopen { $logger.info("websock") {"connection from #{addr}:#{port}"} } sock.onbinary { |msg| begin serv.receive_dgram(msg) rescue => e $logger.error("websock") { "error occured: #{e.message} (#{e.backtrace[0]})" } end } sock.onclose { $logger.info("websock") { "connection close from #{addr}:#{port}" } bye(sock) } } } end
クリティカルセクションの設置
@yield クリティカルセクションとして処理するブロック
@return [Object] ブロックの戻り値
# File lib/ipcam/websock.rb, line 38 def sync(&proc) return (@mutex ||= Mutex.new).synchronize(&proc) end
Private Class Methods
バインド先のURL文字列を生成する
@return [String] URL文字列
# File lib/ipcam/websock.rb, line 102 def bind_url if $bind_addr.include?(":") addr = "[#{$bind_addr}]" if $bind_addr.include?(":") else addr = $bind_addr end return "#{($use_ssl)? "ssl":"tcp"}://#{addr}:#{$ws_port}" end
セッションリストへのセッション追加
@param [Socket] sock セッションリストに追加するソケットオブジェクト
@return [WebSocket]
ソケットオブジェクトに紐付けられたセッションオブジェクト
@note
受け取ったソケットオブジェクトを元に、セッションオブジェクトを 生成し、そのオブジェクトをセッションリストに追加する
# File lib/ipcam/websock.rb, line 54 def join(sock) sync { if session_list.any? {|s| s === sock} raise("Already joined #{sock}") end ret = self.new(@app, sock) session_list << ret return ret } end
セッションリストの取得
@return [Array<WebSocket>] セッションリスト
# File lib/ipcam/websock.rb, line 26 def session_list return @session_list ||= [] end
Public Instance Methods
比較演算子の定義
# File lib/ipcam/websock.rb, line 251 def ===(obj) return (self == obj || @sock == obj) end
通知要求を設定する
@param [Array] arg
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 266 def add_notify_request(*args) args.each {|type| @allow << type.to_sym} args.uniq! return :OK end
通知要求をクリアする
@param [Array] arg
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 281 def clear_notify_request(*args) args.each {|type| @allow.delete(type.to_sym)} return :OK end
セッションオブジェクトの終了処理
# File lib/ipcam/websock.rb, line 200 def finish end
カメラ情報の取得
@return [:OK] カメラ情報をパックしたハッシュ
# File lib/ipcam/websock.rb, line 303 def get_camera_info return @app.get_camera_info() end
カメラの設定情報の取得
@return [Array] カメラの設定情報の配列
# File lib/ipcam/websock.rb, line 323 def get_config return @app.get_config end
カメラ固有名の取得
@return [:OK] カメラ情報をパックしたハッシュ
# File lib/ipcam/websock.rb, line 313 def get_ident_string return @app.get_ident_string() end
疎通確認用プロシジャー
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 293 def hello return :OK end
通知の送信
@param [String] name イベント名 @param [Array] args イベントで通知する引数
# File lib/ipcam/websock.rb, line 244 def notify(name, *args) super(name, *args) if @allow == "*" or @allow.include?(name) end
設定値の保存
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 384 def save_config @app.save_config() return :OK end
カメラの設定変更
@param [Integer] id 設定項目のID @param [Integer] val 新しい設定項目の値
@return [:OK] 固定値
@note 画像サイズの変更に伴い、update_controlイベントがブロード
キャストされる
# File lib/ipcam/websock.rb, line 373 def set_control(num, deno) @app.set_control(num, deno) return :OK end
フレームレートの設定
@param [Integer] num 新しいフレームレートの値(分子) @param [Integer] deno 新しいフレームレートの値(分母)
@return [:OK] 固定値
@note 画像サイズの変更に伴い、update_framerateイベントがブロード
キャストされる
# File lib/ipcam/websock.rb, line 356 def set_framerate(num, deno) @app.set_framerate(num, deno) return :OK end
画像サイズの設定
@param [Integer] width 新しい画像の幅 @param [Integer] height 新しい画像の高さ
@return [:OK] 固定値
@note 画像サイズの変更に伴い、update_image_sizeイベントがブロード
キャストされる
# File lib/ipcam/websock.rb, line 339 def set_image_size(width, height) @app.set_image_size(width, height) return :OK end
カメラの撮影開始
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 395 def start_camera(df) EM.defer { @app.start_camera() df.resolve(:OK) } end
カメラの撮影停止
@return [:OK] 固定値
# File lib/ipcam/websock.rb, line 408 def stop_camera(df) EM.defer { @app.stop_camera() df.resolve(:OK) } end
Private Instance Methods
通知のブロードキャスト
@param [String] name イベント名 @param [Array] args イベントで通知する引数
# File lib/ipcam/websock.rb, line 233 def broadcast(name, *args) self.class.broadcast(name, *arg) end
MessagePack-RPCのエラーハンドリング
@param [StandardError] e 発生したエラーの例外オブジェクト
@note MessagePack::Rpc::Serverのオーバーライド
# File lib/ipcam/websock.rb, line 222 def on_error(e) $logger.error("websock") {e.message} end
peerソケットへのデータ送信
@param [String] data 送信するデータ
@note MessagePack::Rpc::Serverのオーバーライド
# File lib/ipcam/websock.rb, line 210 def send_data(data) @sock.send_binary(data) end