Как отправлять сообщения из клиентского приложения (Dash.js) на OpenFlow Switch

У меня есть клиентское приложение Dash.js, видеоплеер, который работает в среде, эмулирующей сеть SDN с коммутаторами и контроллером открытого потока.

Это приложение адаптирует качество видео к пропускной способности сети пользователя.

Класс, который определяет, будет ли клиент запрашивать замену сегмента для адаптации к доступной пропускной способности, — это AbrController.js.

MediaPlayer.dependencies.AbrController = function () {
    "use strict";

    var autoSwitchBitrate = true,
        qualityDict = {},
        confidenceDict = {},

        getInternalQuality = function (type) {
            var quality;

            if (!qualityDict.hasOwnProperty(type)) {
                qualityDict[type] = 0;
            }

            quality = qualityDict[type];

            return quality;
        },

        setInternalQuality = function (type, value) {
            qualityDict[type] = value;
        },

        getInternalConfidence = function (type) {
            var confidence;

            if (!confidenceDict.hasOwnProperty(type)) {
                confidenceDict[type] = 0;
            }

            confidence = confidenceDict[type];

            return confidence;
        },

        setInternalConfidence = function (type, value) {
            confidenceDict[type] = value;
        };

    return {
        debug: undefined,
        abrRulesCollection: undefined,
        manifestExt: undefined,
        metricsModel: undefined,
        metricsBaselinesModel: undefined,


        getAutoSwitchBitrate: function () {
            return autoSwitchBitrate;
        },

        setAutoSwitchBitrate: function (value) {
            autoSwitchBitrate = value;
        },

        getMetricsFor: function (data) {
            var deferred = Q.defer(),
                self = this;

            self.manifestExt.getIsVideo(data).then(
                function (isVideo) {
                    if (isVideo) {
                        deferred.resolve(self.metricsModel.getMetricsFor("video"));
                    } else {
                        self.manifestExt.getIsAudio(data).then(
                            function (isAudio) {
                                if (isAudio) {
                                    deferred.resolve(self.metricsModel.getMetricsFor("audio"));
                                } else {
                                    deferred.resolve(self.metricsModel.getMetricsFor("stream"));
                                }
                            }
                        );
                    }
                }
            );

            return deferred.promise;
        },
        
        getMetricsBaselineFor: function (data) {
            var deferred = Q.defer(),
                self = this;

            self.manifestExt.getIsVideo(data).then(
                function (isVideo) {
                    if (isVideo) {
                        deferred.resolve(self.metricsBaselinesModel.getMetricsBaselineFor("video"));
                    } else {
                        self.manifestExt.getIsAudio(data).then(
                            function (isAudio) {
                                if (isAudio) {
                                    deferred.resolve(self.metricsBaselinesModel.getMetricsBaselineFor("audio"));
                                } else {
                                    deferred.resolve(self.metricsBaselinesModel.getMetricsBaselineFor("stream"));
                                    //self.debug.log("GET STREAM.");

                                }
                            }
                        );
                    }
                }
            );

            return deferred.promise;
        },

        getPlaybackQuality: function (type, data, availableRepresentations) {
            var self = this,
                deferred = Q.defer(),
                newQuality = MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE,
                newConfidence = MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE,
                i,
                len,
                funcs = [],
                req,
                values,
                quality,
                confidence;

            quality = getInternalQuality(type);

            confidence = getInternalConfidence(type);

            //self.debug.log("ABR enabled? (" + autoSwitchBitrate + ")");

            if (autoSwitchBitrate) {
                //self.debug.log("Check ABR rules.");

              self.getMetricsFor(data).then(
                  function (metrics) {
                    self.getMetricsBaselineFor(data).then(
                      function (metricsBaseline) {
                        self.abrRulesCollection.getRules().then(
                            function (rules) {
                                for (i = 0, len = rules.length; i < len; i += 1) {
                                    funcs.push(rules[i].checkIndex(quality, metrics, data, metricsBaseline, availableRepresentations));
                                }
                                Q.all(funcs).then(
                                    function (results) {
                                        //self.debug.log(results);
                                        values = {};
                                        values[MediaPlayer.rules.SwitchRequest.prototype.STRONG] = MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE;
                                        values[MediaPlayer.rules.SwitchRequest.prototype.WEAK] = MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE;
                                        values[MediaPlayer.rules.SwitchRequest.prototype.DEFAULT] = MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE;

                                        for (i = 0, len = results.length; i < len; i += 1) {
                                            req = results[i];
                                            if (req.quality !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE) {
                                                values[req.priority] = Math.min(values[req.priority], req.quality);
                                            }
                                        }

                                        if (values[MediaPlayer.rules.SwitchRequest.prototype.WEAK] !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE) {
                                            newConfidence = MediaPlayer.rules.SwitchRequest.prototype.WEAK;
                                            newQuality = values[MediaPlayer.rules.SwitchRequest.prototype.WEAK];
                                        }

                                        if (values[MediaPlayer.rules.SwitchRequest.prototype.DEFAULT] !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE) {
                                            newConfidence = MediaPlayer.rules.SwitchRequest.prototype.DEFAULT;
                                            newQuality = values[MediaPlayer.rules.SwitchRequest.prototype.DEFAULT];
                                        }

                                        if (values[MediaPlayer.rules.SwitchRequest.prototype.STRONG] !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE) {
                                            newConfidence = MediaPlayer.rules.SwitchRequest.prototype.STRONG;
                                            newQuality = values[MediaPlayer.rules.SwitchRequest.prototype.STRONG];
                                        }

                                        if (newQuality !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE && newQuality !== undefined) {
                                            quality = newQuality;
                                        }

                                        if (newConfidence !== MediaPlayer.rules.SwitchRequest.prototype.NO_CHANGE && newConfidence !== undefined) {
                                            confidence = newConfidence;
                                        }

                                        self.manifestExt.getRepresentationCount(data).then(
                                            function (max) {
                                                // be sure the quality valid!
                                                if (quality < 0) {
                                                    quality = 0;
                                                }
                                                // zero based
                                                if (quality >= max) {
                                                    quality = max - 1;
                                                }

                                                if (confidence != MediaPlayer.rules.SwitchRequest.prototype.STRONG &&
                                                    confidence != MediaPlayer.rules.SwitchRequest.prototype.WEAK) {
                                                    confidence = MediaPlayer.rules.SwitchRequest.prototype.DEFAULT;
                                                }

                                                setInternalQuality(type, quality);
                                                //self.debug.log("New quality of " + quality);

                                                setInternalConfidence(type, confidence);
                                                //self.debug.log("New confidence of " + confidence);

                                                deferred.resolve({quality: quality, confidence: confidence});
                                            }
                                        );
                                    }
                                );
                            }
                        );
                    }
                );
               }
             );
            } else {
                self.debug.log("Unchanged quality of " + quality);
                deferred.resolve({quality: quality, confidence: confidence});
            }

            return deferred.promise;
        },

        setPlaybackQuality: function (type, newPlaybackQuality) {
            var quality = getInternalQuality(type);

            if (newPlaybackQuality !== quality) {
                setInternalQuality(type, newPlaybackQuality);
            }
        },

        getQualityFor: function (type) {
            return getInternalQuality(type);
        }
    };
};

MediaPlayer.dependencies.AbrController.prototype = {
    constructor: MediaPlayer.dependencies.AbrController
};

Я хочу, чтобы каждый раз, когда есть запрос на изменение сегмента, для коммутатора открытого потока инициировалось сообщение, чтобы он мог отправить пакет на контроллер, и контроллер принял меры.

Для меня сейчас проблема заключается в обмене данными между клиентом и коммутатором OpenFlow.

Кто-нибудь знает, как снять это сообщение и попасть в переключатель openflow?

Благодарю вас!


person Jhenifer Santos    schedule 17.11.2015    source источник


Ответы (1)


Вы можете использовать REST API для передачи параметров в вашу сеть. Большинство контроллеров SDN предоставляют свои API для взаимодействия с внешними приложениями.

REST API Ryu: https://osrg.github.io/ryu-book/en/html/rest_api.html REST API Opendaylight: https://wiki.opendaylight.org/view/OpenDaylight_Controller:REST_Reference_and_Authentication

person Icaro Camelo    schedule 24.11.2015