Class: Faye::Transport::WebSocket

Inherits:
Faye::Transport show all
Includes:
Deferrable
Defined in:
lib/faye/transport/web_socket.rb

Constant Summary collapse

UNCONNECTED =
1
CONNECTING =
2
CONNECTED =
3
PROTOCOLS =
{
  'http'  => 'ws',
  'https' => 'wss'
}

Constants included from Logging

Logging::LOG_LEVELS

Instance Attribute Summary

Attributes inherited from Faye::Transport

#endpoint

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Deferrable

#set_deferred_status

Methods inherited from Faye::Transport

#connection_type, #encode, #flush, #flush_large_batch, get, #handle_error, #initialize, #receive, register, #send

Methods included from Faye::Timeouts

#add_timeout, #remove_all_timeouts, #remove_timeout

Methods included from Publisher

#unbind

Constructor Details

This class inherits a constructor from Faye::Transport

Class Method Details

.create(client, endpoint) ⇒ Object



19
20
21
22
# File 'lib/faye/transport/web_socket.rb', line 19

def self.create(client, endpoint)
  sockets = client.transports[:websocket] ||= {}
  sockets[endpoint.to_s] ||= new(client, endpoint)
end

.usable?(client, endpoint, &callback) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/faye/transport/web_socket.rb', line 15

def self.usable?(client, endpoint, &callback)
  create(client, endpoint).usable?(&callback)
end

Instance Method Details

#batching?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/faye/transport/web_socket.rb', line 24

def batching?
  false
end

#closeObject



109
110
111
112
# File 'lib/faye/transport/web_socket.rb', line 109

def close
  return unless @socket
  @socket.close
end

#connectObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/faye/transport/web_socket.rb', line 46

def connect
  @state ||= UNCONNECTED
  return unless @state == UNCONNECTED
  @state = CONNECTING

  headers = @client.headers.dup
  headers['Cookie'] = get_cookies

  url = @endpoint.dup
  url.scheme = PROTOCOLS[url.scheme]
  socket = Faye::WebSocket::Client.new(url.to_s, [], :headers => headers)

  socket.onopen = lambda do |*args|
    store_cookies(socket.headers['Set-Cookie'])
    @socket = socket
    @state = CONNECTED
    @ever_connected = true
    ping
    set_deferred_status(:succeeded, socket)
  end

  closed = false
  socket.onclose = socket.onerror = lambda do |*args|
    next if closed
    closed = true

    was_connected = (@state == CONNECTED)
    socket.onopen = socket.onclose = socket.onerror = socket.onmessage = nil

    @socket = nil
    @state = UNCONNECTED
    remove_timeout(:ping)
    set_deferred_status(:unknown)

    pending  = @pending ? @pending.to_a : []
    @pending = nil

    if was_connected
      handle_error(pending, true)
    elsif @ever_connected
      handle_error(pending)
    else
      set_deferred_status(:failed)
    end
  end

  socket.onmessage = lambda do |event|
    messages  = MultiJson.load(event.data)
    envelopes = []

    next if messages.nil?
    messages = [messages].flatten

    messages.each do |message|
      next unless message.has_key?('successful')
      next unless envelope = @pending.find { |e| e.id == message['id'] }
      @pending.delete(envelope)
      envelopes << envelope
    end
    receive(envelopes, messages)
  end
end

#request(envelopes) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/faye/transport/web_socket.rb', line 34

def request(envelopes)
  @pending ||= Set.new
  envelopes.each { |envelope| @pending.add(envelope) }

  callback do |socket|
    next unless socket
    messages = envelopes.map { |e| e.message }
    socket.send(Faye.to_json(messages))
  end
  connect
end

#usable?(&callback) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
31
32
# File 'lib/faye/transport/web_socket.rb', line 28

def usable?(&callback)
  self.callback { callback.call(true) }
  self.errback { callback.call(false) }
  connect
end