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インスタンス



185
186
187
188
189
190
191
192
193
# 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

Instance Attribute Details

#sockObject (readonly)

Returns the value of attribute sock.



195
196
197
# File 'lib/ipcam/websock.rb', line 195

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 "#{($use_ssl)? "ssl":"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
167
168
169
170
171
172
173
174
175
176
# 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 { ... } ⇒ 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

比較演算子の定義



251
252
253
# File 'lib/ipcam/websock.rb', line 251

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

#add_notify_request(*args) ⇒ :OK

通知要求を設定する

Parameters:

  • arg (Array)

Returns:

  • (:OK)

    固定値



266
267
268
269
270
271
# 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) ⇒ :OK

通知要求をクリアする

Parameters:

  • arg (Array)

Returns:

  • (:OK)

    固定値



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

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

	return :OK
end

#finishObject

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



200
201
# File 'lib/ipcam/websock.rb', line 200

def finish
end

#get_camera_info:OK

カメラ情報の取得

Returns:

  • (:OK)

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



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

def get_camera_info
  return @app.get_camera_info()
end

#get_configArray

カメラの設定情報の取得

Returns:

  • (Array)

    カメラの設定情報の配列



323
324
325
# File 'lib/ipcam/websock.rb', line 323

def get_config
  return @app.get_config
end

#get_ident_string:OK

カメラ固有名の取得

Returns:

  • (:OK)

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



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

def get_ident_string
  return @app.get_ident_string()
end

#hello:OK

疎通確認用プロシジャー

Returns:

  • (:OK)

    固定値



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

def hello
  return :OK
end

#notify(name, *args) ⇒ Object

通知の送信

Parameters:

  • name (String)

    イベント名

  • args (Array)

    イベントで通知する引数



244
245
246
# File 'lib/ipcam/websock.rb', line 244

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

#save_config:OK

設定値の保存

Returns:

  • (:OK)

    固定値



384
385
386
387
# File 'lib/ipcam/websock.rb', line 384

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)

    固定値



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

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)

    固定値



356
357
358
359
# 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) ⇒ :OK

Note:

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

画像サイズの設定

Parameters:

  • width (Integer)

    新しい画像の幅

  • height (Integer)

    新しい画像の高さ

Returns:

  • (:OK)

    固定値



339
340
341
342
# 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) ⇒ :OK

カメラの撮影開始

Returns:

  • (:OK)

    固定値



395
396
397
398
399
400
# File 'lib/ipcam/websock.rb', line 395

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

#stop_camera(df) ⇒ :OK

カメラの撮影停止

Returns:

  • (:OK)

    固定値



408
409
410
411
412
413
# File 'lib/ipcam/websock.rb', line 408

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