web-dev-qa-db-fra.com

Comment utiliser ActionCable comme API

J'ai construit une application très simple en utilisant Rails 5 beta 1 et ActionCable pour montrer quand les utilisateurs se connectent et les laisser s'envoyer des messages.

Maintenant, je voudrais essentiellement prendre la partie côté client d'ActionCable, l'implémenter dans le contexte d'une autre application (qui ne pas s'exécute sur Rails 5) et connectez-le avec la première application pour envoyer et recevoir des données (telles que le statut en ligne des utilisateurs ou des messages).

Pour envoyer des données à partir de cette deuxième application, je suppose que je peux simplement faire une AJAX POST. La question est: Comment puis-je m'abonner) de ma deuxième application à une connexion ouverte de la première application?

Ou même: Comment puis-je m'abonner à la connexion ActionCable de mon application Rails d'une autre application via l'API?

Je suppose que je veux essentiellement inclure ce scénario dans ma deuxième application:

App.appearance = App.cable.subscriptions.create "AppearanceChannel",
  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    # ...
19
sam

Bien que la solution de mwalsher m'ait été extrêmement utile, j'ai récemment trouvé une demande d'extraction sur le dépôt Rails avec une solution officielle à ma question.

https://github.com/Rails/rails/pull/24991

Je suppose que, dans un proche avenir, cela sera ajouté à la documentation principale. Voici le lien vers le package npm officiel d'actioncable: https://www.npmjs.com/package/actioncable

Vous pouvez l'utiliser de la même manière que la solution de mwalsher avec n'importe quelle application JS. Installez simplement le paquet npm:

npm install actioncable --save

Voici l'exemple JS de la documentation:

ActionCable = require('actioncable')

var cable = ActionCable.createConsumer('wss://Rails-API-PATH.com/cable')

cable.subscriptions.create('AppearanceChannel', {
  // normal channel code goes here...
});

Edit: La demande de tirage a été fusionnée pendant un certain temps, maintenant et la description fait partie de l'officiel Readme - juste pas pourtant dans les Rails Guides.

21
sam

Vous devrez essentiellement inclure une copie ou un port du code ActionCable JS dans votre autre application ( https://github.com/Rails/rails/tree/master/actioncable/app/assets/javascripts =).

Mise à jour: j'ai récemment publié un package npm appelé actioncable-js qui fournit un port direct de Ruby on Rails 5 ActionCable CofeeScript vers JS standard pour une utilisation en dehors de Rails) : https://github.com/mwalsher/actioncable-js

Étant donné qu'ActionCable n'est qu'une couche au-dessus de WebSockets HTML5, vous pouvez également utiliser du code JS WebSockets brut (ou toute bibliothèque tierce) pour gérer la messagerie.

Le protocole de message ActionCable est quelque peu documenté ici: https://github.com/NullVoxPopuli/action_cable_client#the-action-cable-protocol . Je vais coller ci-dessous pour plus de commodité:

  1. Connectez-vous à l'URL du câble d'action
  2. Une fois la connexion établie, envoyez un message d'abonnement

    • Le message d'abonnement JSON devrait ressembler à ceci: {"command":"subscribe","identifier":"{\"channel\":\"MeshRelayChannel\"}"}
    • Vous devriez recevoir un message comme celui-ci: {"identifier"=>"{\"channel\":\"MeshRelayChannel\"}", "type"=>"confirm_subscription"}
  3. Une fois inscrit, vous pouvez envoyer des messages.

    • Assurez-vous que la chaîne d'action correspond au nom de la méthode de traitement des données sur votre serveur ActionCable.
    • Votre message JSON devrait ressembler à ceci: {"command":"message","identifier":"{\"channel\":\"MeshRelayChannel\"}","data":"{\"to\":\"user1\",\"message\":\"hello from user2\",\"action\":\"chat\"}"}
    • Les messages reçus doivent avoir la même apparence
  4. Remarques:

    • Chaque message envoyé au serveur possède une clé de commande et d'identification.
    • La valeur de canal doit correspondre au nom de la classe de canal sur le serveur ActionCable.
    • identifier et data sont jsonifiés de manière redondante.

Ainsi, par exemple (en Ruby)

payload = {
  command: 'command text',
  identifier: { channel: 'MeshRelayChannel' }.to_json,
  data: { to: 'user', message: 'hi', action: 'chat' }.to_json
}.to_json
21
mwalsher