9
votes

L'architecture d'un lecteur de musique avec des listes de lecture, utilisant des rails, Redis et HTML5

Je développe une application qui possède plusieurs listes de lecture de musique, une vue pour chaque playlist et un joueur.

Je fais une utilisation du API HTML5 Historique dans mon système déjà (pour d'autres fonctionnalités) et Utilisez-le en outre pour éviter les recharges de la page entre les demandes et donc la musique s'arrête sur chaque page.

Je suis coincé sur la meilleure approche pour gérer les pistes que le joueur jouera entre cependant. À l'heure actuelle, comme vous l'attendez, un utilisateur clique sur un lien, obtient une liste de pistes. Les pistes sont chargées dans le joueur et jouées séquentiellement, simples. Cependant, avec la musique de lecture continue, je dois vous assurer que la liste de lecture correcte des pistes joue dans l'ordre malgré le changement de contenu de la page et c'est maintenant une URL dynamique.

Toutefois, lorsque l'utilisateur navigue vers une autre page, appuyez sur la lecture sur une piste dans la nouvelle liste de lecture, je dois pouvoir charger cet élément dans le lecteur et se charger efficacement dans le reste de la liste de lecture pendant que l'utilisateur continue de Naviguer.

J'utilise ReDIS pour stocker une liste des identifiants de piste pour une liste de lecture, pour un référencement rapide pour réduire le décalage entre les pistes. En conséquence, j'ai une nouvelle lecture de Redis pour chaque liste de lecture. J'ai également construit mes appels d'API de piste suivants et précédents basés sur la lecture actuelle de la piste, de sorte que la piste suivante de Redis Set peut être chargée dans le lecteur.

Comme mentionné, même si je ne peux tout simplement pas décider de la meilleure façon de faire référence à la liste de lecture en cours de lecture afin que le joueur sait à partir desquels ReDIS a défini pour appeler les pistes de. Ma pensée m'a laissé quelques idées différentes:

a) Attributs de données personnalisés HTML5 - Je pourrais définir la liste de lecture en cours de lecture en tant qu'attribut de données sur le lecteur et le mettre à jour comme. Je pourrais alors faire référence à cet attribut lors de la décision de laquelle REDIS définit pour charger ma prochaine piste de.

Vous pouvez également jeter la liste de lecture actuelle et toutes les pistes (et leurs attributs) en tant qu'objets JSON dans des attributs de données sur la page. Les playlists pourraient être des milliers de pistes bien cependant que je suis donc en train de rejeter celui-ci parce que le code source serait horrible, sans parler des problèmes de performance probables associés. Ai-je raison?

b) localStorage - le support de navigateur croisé est limité. Plus la solution pour cette solution est la meilleure dans ce cas particulier. Malgré cela, je pouvais enregistrer la liste de lecture actuelle dans le navigateur des utilisateurs. Cela m'a amené à me demander s'il serait également pratique d'enregistrer les objets JSON de pistes dans localStorage également pour empêcher les appels de DB supplémentaires.

c) en session - Je pourrais mettre à jour la session pour stocker une variable pour la liste de lecture en cours de lecture.

d) REDIS - Je pourrais développer mon utilisation de Redis pour enregistrer une chaîne qui fait référence au nom de la liste de lecture actuelle. Je pourrais ensuite le vérifier entre chaque appel de piste suivant / précédent.

En écrivant cette question, j'ai déjà une meilleure idée de la route que je vais prendre, mais si quelqu'un a des conseils à ce scénario, j'aimerais bien entendre s'il vous plaît.

Merci.

mise à jour: J'ai mis en œuvre 95% d'une solution qui utilise Redis pour cela. Je saisra quelques problèmes de performance avec des pages prenant ~ 10 à charger. Pas grand du tout.

Essentiellement, chaque utilisateur dispose de 2 listes de lecture: actuelles et armées. Chaque requête charge l'identifiant de la piste dans la liste de lecture armée Redis et si le bouton de lecture est enfoncé sur une piste, la liste de lecture de Redis actuelle est expirée et remplacée par l'armée armée.

Mes boutons suivants et précédents, passez simplement l'identifiant de la piste suivante ou précédente dans la liste de lecture actuelle et chargez-vous dans la source de musique pour le lecteur. Le concept fonctionne bien et je suis satisfait de cela.

Cependant, comme indiqué que les performances sont lentes entre les demandes de page et nécessitent une amélioration significative. Mon SQL est optimisé, je tire seulement les attributs requis et j'ai des index SQL si nécessaire, donc je cherche d'autres alternatives pour le moment.

options que je considère:

  1. peupler uniquement la liste de lecture armée si une piste est cliquée sur la nouvelle page. Cela permettrait d'économiser du traitement supplémentaire si l'utilisateur ne souhaite pas réellement écouter l'une des nouvelles pistes.

  2. Fabriquez plus d'utilisation de Redis et de stocker les objets de piste maigre dans les listes de lecture de Redis au lieu de simplement l'ID de piste - Le décalage de la performance est en grande partie entre les demandes de page et non dans le jeu actuel des pistes et la navigation dans une playlist.

  3. Utilisez une playlist Master Redis contenant toutes les pistes d'applications à partir desquelles les listes de lecture actuelles et armées peuvent choisir. Cela pourrait être maintenu via une tâche de râteau horaire et empêcherait de longs appels de DB sur les demandes de page. Je suis juste nerveux à quelle distance cela permettrait d'économiser en termes d'utilisation de la mémoire sur le serveur et à la quantité de pistes dans la DB.


0 commentaires

3 Réponses :


0
votes

Je suggérerais c) en session.
Les données de session sont accessibles avec une relative facilité de la part des clients et du serveur.

Remplissage de votre cache Redis avec des données d'utilisateur spécifiques ne permet pas de réduire particulièrement bien.

localStorage - Correct, cela échouera pour un grand% des utilisateurs à la date actuelle.

Attributs CustomData - Tout simplement désordonné, comme indiqué.

juste mes 2 cents.


0 commentaires

1
votes

Si vous avez besoin de modéliser l'état de l'application côté client, il est préférable d'avoir une source de l'état. Ceci est celui des cadres de la CLIENT MV JavaScript MV (V) CANS CLIENT CLIENT CLIENT Thanne de résoudre. Je connais principalement Backbone.js et ember.js afin que je puisse parler à ceux-ci.

Backbone.js

Créer un modèle appelé Playlist et une collection appelée listes de lecture . Ajoutez une propriété à votre listes de lecture Collection CurrentPlayList qui contient la liste de lecture actuelle. Définissez ensuite une vue appelée playlistview et définissez un rendu méthode sur elle. Les déclencheurs d'événement et les liaisons de câbles tels que lorsque CurrentClayListList Modifications, la liste de lecture est automatiquement re-rendue. Cela nécessiterait de déplacer votre modèle de rendu au client, mais vous voudrez probablement le faire de toute façon pour réduire les arrondissements de serveur et réduire la charge sur le serveur causé par le rendu.

ember.js

Créer un contrôleur (similaire à la collection de sackbone) avec une propriété appelée CurrentPlayList et peupler le contrôleur avec toutes les listes de lecture représentées comme Ember.Object s. Ensuite, dans un modèle de guidon de playlist inclus sur la page, vous pouvez lier à listes de lecture.CurrentPlaylist et le modèle rendu automatiquement lorsque lishlists.CurrentPlaylist modifications.

Je quitte évidemment la grande majorité des détails, mais ceux-ci sont mieux laissés la documentation de cadre, des exemples et des tutoriels.

Disclaimer : Je suis nouveau dans des cadres côté client qui fait partie de la raison pour laquelle j'ai laissé la plupart des détails. J'apprécie quiconque qui peut me corriger si je suis en erreur.


1 commentaires

Merci pour la suggestion Patrick. Je ne suis pas encore allé dans le cadre JavaScript MVC, mais je n'ai aucun doute qu'un peu plus loin dans la ligne, il peut être nécessaire pour faciliter la charge du serveur.



1
votes

Un mélange de session et de stockage local serait une bonne approche.

Mais au lieu d'aller chercher la liste de lecture entière, vient de chercher le x (par exemple 10) Suivant les pistes et peut-être aussi les x précédents. Une fois que le joueur arrive à la dernière chanson, il récupère les 10 prochaines chansons, les précédents peuvent être calculés dans le client.

Le modèle de données pourrait être juste un hasch où l'élément [0] est la chanson actuelle, les éléments [x] sont les prochaines chansons et [-x] les précédentes.

Stockage du côté de l'information de la liste de lecture semble raisonnable pour moi, mais vous pouvez également utiliser la session pour référencer la chanson et la liste de lecture actuelles, alors lorsqu'un utilisateur revient ou recharge vraiment votre site, vous obtenez toujours la chanson sans créer une base de données appelez.


1 commentaires

Cela semble semblable à l'approche que j'ai réellement rendue. J'açais quelques problèmes de performance, car je reçois actuellement la playlist entière à l'heure actuelle, ce qui va simplement être exponentiellement plus lent alors que de plus en plus de pistes sont ajoutées à chaque playlist. Je suis au milieu de la mise en œuvre comme vous l'avez suggéré cependant, vragez simplement les 10 prochaines pistes environ et quand j'atteigne le dernier, allez-y attraper un peu plus. Merci pour la suggestion.