aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/javascript/action_cable/consumer.js
blob: e2e0dea8b5fefa1cd0d6877b0fd28b6aec99d88b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
import Connection from "./connection"
import Subscriptions from "./subscriptions"

// The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,
// the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.
// The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription
// method.
//
// The following example shows how this can be setup:
//
//   App = {}
//   App.cable = ActionCable.createConsumer("ws://example.com/accounts/1")
//   App.appearance = App.cable.subscriptions.create("AppearanceChannel")
//
// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.
//
// When a consumer is created, it automatically connects with the server.
//
// To disconnect from the server, call
//
//   App.cable.disconnect()
//
// and to restart the connection:
//
//   App.cable.connect()
//
// Any channel subscriptions which existed prior to disconnecting will
// automatically resubscribe.

export default class Consumer {
  constructor(url) {
    this._url = url
    this.subscriptions = new Subscriptions(this)
    this.connection = new Connection(this)
  }

  get url() {
    return createWebSocketURL(this._url)
  }

  send(data) {
    return this.connection.send(data)
  }

  connect() {
    return this.connection.open()
  }

  disconnect() {
    return this.connection.close({allowReconnect: false})
  }

  ensureActiveConnection() {
    if (!this.connection.isActive()) {
      return this.connection.open()
    }
  }
}

export function createWebSocketURL(url) {
  if (typeof url === "function") {
    url = url()
  }

  if (url && !/^wss?:/i.test(url)) {
    const a = document.createElement("a")
    a.href = url
    // Fix populating Location properties in IE. Otherwise, protocol will be blank.
    a.href = a.href
    a.protocol = a.protocol.replace("http", "ws")
    return a.href
  } else {
    return url
  }
}