Class: Faye::Transport::WebSocket

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

Defined Under Namespace

Classes: Request

Constant Summary collapse

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

Constants inherited from Faye::Transport

DEFAULT_PORTS

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, connection_types, #encode, get, #initialize, register, #send_message

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(dispatcher, endpoint) ⇒ Object



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

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

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

Returns:

  • (Boolean)


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

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

Instance Method Details

#batching?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/faye/transport/web_socket.rb', line 32

def batching?
  false
end

#closeObject



124
125
126
127
# File 'lib/faye/transport/web_socket.rb', line 124

def close
  return unless @socket
  @socket.close
end

#connectObject



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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/faye/transport/web_socket.rb', line 58

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

  url        = @endpoint.dup
  headers    = @dispatcher.headers.dup
  extensions = @dispatcher.ws_extensions
  cookie     = get_cookies

  url.scheme = PROTOCOLS[url.scheme]
  headers['Cookie'] = cookie unless cookie == ''

  options = {
    :extensions => extensions,
    :headers    => headers,
    :proxy      => @proxy,
    :tls        => @dispatcher.tls
  }

  socket = Faye::WebSocket::Client.new(url.to_s, [], options)

  socket.onopen = lambda do |*args|
    store_cookies(socket.headers['Set-Cookie'])
    @socket = socket
    @state = CONNECTED
    @ever_connected = true
    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

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

    if was_connected or @ever_connected
      set_deferred_status(:unknown)
      handle_error(pending, was_connected)
    else
      set_deferred_status(:failed)
    end
  end

  socket.onmessage = lambda do |event|
    replies = MultiJson.load(event.data) rescue nil
    next if replies.nil?
    replies = [replies].flatten

    replies.each do |reply|
      next unless reply.has_key?('successful')
      next unless message = @pending.find { |m| m['id'] == reply['id'] }
      @pending.delete(message)
    end
    receive(replies)
  end
end

#request(messages) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/faye/transport/web_socket.rb', line 42

def request(messages)
  @pending ||= Set.new
  messages.each { |message| @pending.add(message) }

  promise = Request.new

  callback do |socket|
    next unless socket and socket.ready_state == 1
    socket.send(Faye.to_json(messages))
    promise.succeed(socket)
  end

  connect
  promise
end

#usable?(&callback) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
39
40
# File 'lib/faye/transport/web_socket.rb', line 36

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