Class: IPCam::WebSocket

Inherits:
Object
  • Object
show all
Includes:
MessagePack::Rpc::Server
Defined in:
lib/ipcam/websock.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, sock) ⇒ WebSocket

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

Parameters:

  • app (IPCam)

    アプリケーション本体のインスタンス

  • sock (Socket)

    Socketインスタンス



175
176
177
178
179
180
181
182
183
# File 'lib/ipcam/websock.rb', line 175

def initialize(app, sock)
  @app   = app
  @sock  = sock
  @allow = []

  peer   = Socket.unpack_sockaddr_in(sock.get_peername)
  @addr  = peer[1]
  @port  = peer[0]
end

Instance Attribute Details

#sockObject (readonly)

Returns the value of attribute sock.



185
186
187
# File 'lib/ipcam/websock.rb', line 185

def sock
  @sock
end

Class Method Details

.bind_urlString

バインド先のURL文字列を生成する

Returns:

  • (String)

    URL文字列



102
103
104
105
106
107
108
109
110
# 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 "tcp://#{addr}:#{$ws_port}"
end

.broadcast(name, *args) ⇒ Object

イベント情報の一斉送信

Parameters:

  • name (String)

    イベント名

  • args (Array)

    イベントで通知する引数



93
94
95
# File 'lib/ipcam/websock.rb', line 93

def broadcast(name, *args)
  sync {session_list.each {|s| s.notify(name, *args)}}
end

.bye(sock) ⇒ Object

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

Parameters:

  • sock (Socket)

    セッションオブジェクトを特定するためのソケットオブジェクト



74
75
76
77
78
79
80
81
82
83
84
85
# 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

.join(sock) ⇒ WebSocket

Note:

受け取ったソケットオブジェクトを元に、セッションオブジェクトを生成し、そのオブジェクトをセッションリストに追加する

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

Parameters:

  • sock (Socket)

    セッションリストに追加するソケットオブジェクト

Returns:

  • (WebSocket)

    ソケットオブジェクトに紐付けられたセッションオブジェクト



54
55
56
57
58
59
60
61
62
63
64
65
# 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_listArray<WebSocket>

セッションリストの取得

Returns:

  • (Array<WebSocket>)

    セッションリスト



26
27
28
# File 'lib/ipcam/websock.rb', line 26

def session_list
  return @session_list ||= []
end

.start(app) ⇒ Object

WebSocket制御の開始



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# 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()})"}

    EM::WebSocket.start(:host => $bind_addr, :port => $ws_port) { |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 { ... } ⇒ Object

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

Yields:

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

Returns:

  • (Object)

    ブロックの戻り値



38
39
40
# File 'lib/ipcam/websock.rb', line 38

def sync(&proc)
  return (@mutex ||= Mutex.new).synchronize(&proc)
end

Instance Method Details

#===(obj) ⇒ Object

比較演算子の定義



241
242
243
# File 'lib/ipcam/websock.rb', line 241

def ===(obj)
  return (self == obj || @sock == obj)
end

#add_notify_request(*args) ⇒ :OK

通知要求を設定する

Parameters:

  • arg (Array)

Returns:

  • (:OK)

    固定値



256
257
258
259
260
261
# File 'lib/ipcam/websock.rb', line 256

def add_notify_request(*args)
  args.each {|type| @allow << type.to_sym}
  args.uniq!

  return :OK
end

#clear_notify_request(*args) ⇒ :OK

通知要求をクリアする

Parameters:

  • arg (Array)

Returns:

  • (:OK)

    固定値



271
272
273
274
275
# File 'lib/ipcam/websock.rb', line 271

def clear_notify_request(*args)
  args.each {|type| @allow.delete(type.to_sym)}

  return :OK
end

#finishObject

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



190
191
# File 'lib/ipcam/websock.rb', line 190

def finish
end

#get_camera_info:OK

カメラ情報の取得

Returns:

  • (:OK)

    カメラ情報をパックしたハッシュ



293
294
295
# File 'lib/ipcam/websock.rb', line 293

def get_camera_info
  return @app.get_camera_info()
end

#get_configArray

カメラの設定情報の取得

Returns:

  • (Array)

    カメラの設定情報の配列



313
314
315
# File 'lib/ipcam/websock.rb', line 313

def get_config
  return @app.get_config
end

#get_ident_string:OK

カメラ固有名の取得

Returns:

  • (:OK)

    カメラ情報をパックしたハッシュ



303
304
305
# File 'lib/ipcam/websock.rb', line 303

def get_ident_string
  return @app.get_ident_string()
end

#hello:OK

疎通確認用プロシジャー

Returns:

  • (:OK)

    固定値



283
284
285
# File 'lib/ipcam/websock.rb', line 283

def hello
  return :OK
end

#notify(name, *args) ⇒ Object

通知の送信

Parameters:

  • name (String)

    イベント名

  • args (Array)

    イベントで通知する引数



234
235
236
# File 'lib/ipcam/websock.rb', line 234

def notify(name, *args)
  super(name, *args) if @allow == "*" or @allow.include?(name)
end

#save_config:OK

設定値の保存

Returns:

  • (:OK)

    固定値



374
375
376
377
# File 'lib/ipcam/websock.rb', line 374

def save_config
  @app.save_config()
  return :OK
end

#set_control(num, deno) ⇒ :OK

Note:

画像サイズの変更に伴い、update_controlイベントがブロードキャストされる

カメラの設定変更

Parameters:

  • id (Integer)

    設定項目のID

  • val (Integer)

    新しい設定項目の値

Returns:

  • (:OK)

    固定値



363
364
365
366
# File 'lib/ipcam/websock.rb', line 363

def set_control(num, deno)
  @app.set_control(num, deno)
  return :OK
end

#set_framerate(num, deno) ⇒ :OK

Note:

画像サイズの変更に伴い、update_framerateイベントがブロードキャストされる

フレームレートの設定

Parameters:

  • num (Integer)

    新しいフレームレートの値(分子)

  • deno (Integer)

    新しいフレームレートの値(分母)

Returns:

  • (:OK)

    固定値



346
347
348
349
# File 'lib/ipcam/websock.rb', line 346

def set_framerate(num, deno)
  @app.set_framerate(num, deno)
  return :OK
end

#set_image_size(width, height) ⇒ :OK

Note:

画像サイズの変更に伴い、update_image_sizeイベントがブロードキャストされる

画像サイズの設定

Parameters:

  • width (Integer)

    新しい画像の幅

  • height (Integer)

    新しい画像の高さ

Returns:

  • (:OK)

    固定値



329
330
331
332
# File 'lib/ipcam/websock.rb', line 329

def set_image_size(width, height)
  @app.set_image_size(width, height)
  return :OK
end

#start_camera(df) ⇒ :OK

カメラの撮影開始

Returns:

  • (:OK)

    固定値



385
386
387
388
389
390
# File 'lib/ipcam/websock.rb', line 385

def start_camera(df)
  EM.defer {
    @app.start_camera()
    df.resolve(:OK)
  }
end

#stop_camera(df) ⇒ :OK

カメラの撮影停止

Returns:

  • (:OK)

    固定値



398
399
400
401
402
403
# File 'lib/ipcam/websock.rb', line 398

def stop_camera(df)
  EM.defer {
    @app.stop_camera()
    df.resolve(:OK)
  }
end