class IPCam::WebSocket

Attributes

sock[R]

Public Class Methods

broadcast(name, *args) click to toggle source

イベント情報の一斉送信

@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
bye(sock) click to toggle source

セッションオブジェクトからのセッション削除

@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
new(app, sock) click to toggle source

セッションオブジェクトのイニシャライザ

@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
start(app) click to toggle source

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
sync(&proc) click to toggle source

クリティカルセクションの設置

@yield クリティカルセクションとして処理するブロック

@return [Object] ブロックの戻り値

# File lib/ipcam/websock.rb, line 38
def sync(&proc)
  return (@mutex ||= Mutex.new).synchronize(&proc)
end

Private Class Methods

bind_url() click to toggle source

バインド先の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
join(sock) click to toggle source

セッションリストへのセッション追加

@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
session_list() click to toggle source

セッションリストの取得

@return [Array<WebSocket>] セッションリスト

# File lib/ipcam/websock.rb, line 26
def session_list
  return @session_list ||= []
end

Public Instance Methods

===(obj) click to toggle source

比較演算子の定義

# File lib/ipcam/websock.rb, line 251
def ===(obj)
  return (self == obj || @sock == obj)
end
add_notify_request(*args) click to toggle source

通知要求を設定する

@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
clear_notify_request(*args) click to toggle source

通知要求をクリアする

@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
finish() click to toggle source

セッションオブジェクトの終了処理

# File lib/ipcam/websock.rb, line 200
def finish
end
get_camera_info() click to toggle source

カメラ情報の取得

@return [:OK] カメラ情報をパックしたハッシュ

# File lib/ipcam/websock.rb, line 303
def get_camera_info
  return @app.get_camera_info()
end
get_config() click to toggle source

カメラの設定情報の取得

@return [Array] カメラの設定情報の配列

# File lib/ipcam/websock.rb, line 323
def get_config
  return @app.get_config
end
get_ident_string() click to toggle source

カメラ固有名の取得

@return [:OK] カメラ情報をパックしたハッシュ

# File lib/ipcam/websock.rb, line 313
def get_ident_string
  return @app.get_ident_string()
end
hello() click to toggle source

疎通確認用プロシジャー

@return [:OK] 固定値

# File lib/ipcam/websock.rb, line 293
def hello
  return :OK
end
notify(name, *args) click to toggle source

通知の送信

@param [String] name イベント名 @param [Array] args イベントで通知する引数

Calls superclass method
# File lib/ipcam/websock.rb, line 244
def notify(name, *args)
  super(name, *args) if @allow == "*" or @allow.include?(name)
end
save_config() click to toggle source

設定値の保存

@return [:OK] 固定値

# File lib/ipcam/websock.rb, line 384
def save_config
  @app.save_config()
  return :OK
end
set_control(num, deno) click to toggle source

カメラの設定変更

@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
set_framerate(num, deno) click to toggle source

フレームレートの設定

@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
set_image_size(width, height) click to toggle source

画像サイズの設定

@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
start_camera(df) click to toggle source

カメラの撮影開始

@return [:OK] 固定値

# File lib/ipcam/websock.rb, line 395
def start_camera(df)
  EM.defer {
    @app.start_camera()
    df.resolve(:OK)
  }
end
stop_camera(df) click to toggle source

カメラの撮影停止

@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

broadcast(name, *args) click to toggle source

通知のブロードキャスト

@param [String] name イベント名 @param [Array] args イベントで通知する引数

# File lib/ipcam/websock.rb, line 233
def broadcast(name, *args)
  self.class.broadcast(name, *arg)
end
on_error(e) click to toggle source

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
send_data(data) click to toggle source

peerソケットへのデータ送信

@param [String] data 送信するデータ

@note MessagePack::Rpc::Serverのオーバーライド

# File lib/ipcam/websock.rb, line 210
def send_data(data)
  @sock.send_binary(data)
end