如果客户被判处两个主题,如何区分来自Mercure Hub的一个或另一个主题的数据

发布于 2025-01-19 11:14:13 字数 5545 浏览 1 评论 0原文

我在带有两个Chartjs图的同音应用程序上有AA仪表板,一个用于温度数据,另一个用于压力数据。我需要在实时更新两者;为此,我尝试使用MercureBundle与两个主题:['REALTIME-NOTIF/温度/{sensorId}','Realtime-notif/struct/struct/{sensorId}']。尽管主题听起来相似,但符合数据的逻辑是不同的,因为两个图表J是不同的,并且为此,我有两个带有AMQP队列的Messenger消息处理程序,一个是在topic 'READTIME/notif/note-notif/deverip/demperiation/weettim/ {sensorId}'和其他消息处理程序类在'Realtime-notif/struct/{sensorid}'中发布。我将尝试总结代码简洁。

#mercure.yaml:
mercure:
    hubs:
        default:
            url: '%env(MERCURE_URL)%'
            public_url: '%env(MERCURE_PUBLIC_URL)%'
            jwt:
                secret: '%env(MERCURE_JWT_SECRET)%'
                publish: ['realtime-notif/temperature/{sensorId}', 'realtime-notif/pressure/{sensorId}']
                subscribe: ['realtime-notif/temperature/{sensorId}', 'realtime-notif/pressure/{sensorId}']

#The TemperatureMessageHandler class: 
class TemperatureMessageHandler implements MessageHandlerInterface
{

    private $mercureHub;
    private $managerRegistry;

    public function __construct(HubInterface $mercureHub, ManagerRegistry $managerRegistry)
    {
        $this->mercureHub = $mercureHub;
        $this->managerRegistry = managerRegistry;
    }

    public function __invoke(TemperatureMessage $message)
    {
        try {
            $graphId=$message->getGraphId();
            $lastElapsedTime=$message->getLastElapsedTime();
            
            $em=$this->managerRegistry->getManager();

            $storedData = $em->getRepository(Temperature::class)->findLastRecordsForGraph($graphId, $lastElapsedTime);
            
            /**
             Set the data source for the temperature graph to a specific format from $toredData
            **/
            $formatedChartData = [];
                **....**

            $update = new Update(
                    sprintf('realtime-notif/temperature/%s', $graphId),
                    \json_encode($$formatedChartData),
                    true
            );

            $this->mercureHub->publish($update);
        } catch (\Exception $exc) {
            
        }
    }
}

而且,

#The PressureMessageHandler class:
 class PressureMessageHandler implements MessageHandlerInterface
{

    private $mercureHub;
    private $managerRegistry;

    public function __construct(HubInterface $mercureHub, ManagerRegistry $managerRegistry)
    {
        $this->mercureHub = $mercureHub;
        $this->managerRegistry = managerRegistry;
    }

    public function __invoke(PressureMessage $message)
    {
        try {
            $graphId = $message->getGraphId();
            $lastElapsedTime = $message->getLastElapsedTime();
            
            $em = $this->managerRegistry->getManager();

            $storedData = $em->getRepository(Pressure::class)->findLastRecordsForGraph($graphId, $lastElapsedTime);
            
            /**
             Set the data source for the pressure graph to a specific format from $toredData
            **/
            $formatedChartData = [];
                **....**
            

            $update = new Update(
                    sprintf('realtime-notif/pressure/%s', $graphId),
                    \json_encode($$formatedChartData),
                    true
            );

            $this->mercureHub->publish($update);
        } catch (\Exception $exc) {
            
        }
    }
}

对我的问题是,如果从Mercure Hub接收到的数据是从温度主题或压力主题中的Eventsource对象的消息事件中,我不知道如何区分客户端。

<script type="text/javascript">
                $(document).ready(function () {
                    /**Create two graph on page ready **/
                    let temperatureGraphObject = createTemperatureGraph(canvasTemperaturaGraph);
                    let pressureGRaphObject = createPressureGraph(canvasPressureGraph);
                    
                    /** 
                    I have two function updateTemperatureGraph(temperatureGraphObject, newTemperaturaData) and updatePressureGraph(pressureGraphObject, newPresureData)
                    **/
                    
                    /**Subscribe client to topics for data updates **/
                    {% set topics = ['realtime-notif/temperature/'~temperatureSensorId, 'realtime-notif/pressure/'~pressureSensorId] %}

                    const eventSource = new EventSource("{{ mercure(topics, { subscribe:topics})|escape('js')}}", {withCredentials: true});

                    eventSource.onopen = function () {
                        console.log('New socket connection!');
                    };

                    eventSource.onmessage = function (e) {
                        console.log('New data received');
                        var data = JSON.parse(e.data);
                        
                        /** 
                        The problem is here, how differentiate the topics data to call updateTemperaturaGraph(temperatureGraphObject, data) or  updatePressureGraph(pressureGraphObject, data)
                        **/                     
                    };

                    eventSource.onerror = function () {
                        console.log('Socket connection lost!');
                    };
                });
            </script>

因此,如何区分主题数据以调用updateTemperaturaph(温度graphobject,data)或updatePressuregraph(supplyGraphObject,data)为onMessage事件?

如果我仅将客户端订阅一个主题,则所有收到的数据将是主题图,当然,该图的更新正确。

I have a a dashboard on a Symony app with two ChartJS graphs, one for temperature data, and the other for pressure data. I need update both on realtime; for that purpose I try to use MercureBundle with two topics: ['realtime-notif/temperature/{sensorId}', 'realtime-notif/pressure/{sensorId}']. Although the topics sound similar, the logic to conform datas are differents because the two ChartJS are differents, and for that I have two Messenger messages handlers with AMQP queue, one publish a mercure update in topic 'realtime-notif/temperature/{sensorId}' and the other message handler class publish in 'realtime-notif/pressure/{sensorId}'. I will try to summarize the code to be concise.

#mercure.yaml:
mercure:
    hubs:
        default:
            url: '%env(MERCURE_URL)%'
            public_url: '%env(MERCURE_PUBLIC_URL)%'
            jwt:
                secret: '%env(MERCURE_JWT_SECRET)%'
                publish: ['realtime-notif/temperature/{sensorId}', 'realtime-notif/pressure/{sensorId}']
                subscribe: ['realtime-notif/temperature/{sensorId}', 'realtime-notif/pressure/{sensorId}']

#The TemperatureMessageHandler class: 
class TemperatureMessageHandler implements MessageHandlerInterface
{

    private $mercureHub;
    private $managerRegistry;

    public function __construct(HubInterface $mercureHub, ManagerRegistry $managerRegistry)
    {
        $this->mercureHub = $mercureHub;
        $this->managerRegistry = managerRegistry;
    }

    public function __invoke(TemperatureMessage $message)
    {
        try {
            $graphId=$message->getGraphId();
            $lastElapsedTime=$message->getLastElapsedTime();
            
            $em=$this->managerRegistry->getManager();

            $storedData = $em->getRepository(Temperature::class)->findLastRecordsForGraph($graphId, $lastElapsedTime);
            
            /**
             Set the data source for the temperature graph to a specific format from $toredData
            **/
            $formatedChartData = [];
                **....**

            $update = new Update(
                    sprintf('realtime-notif/temperature/%s', $graphId),
                    \json_encode($formatedChartData),
                    true
            );

            $this->mercureHub->publish($update);
        } catch (\Exception $exc) {
            
        }
    }
}

And,

#The PressureMessageHandler class:
 class PressureMessageHandler implements MessageHandlerInterface
{

    private $mercureHub;
    private $managerRegistry;

    public function __construct(HubInterface $mercureHub, ManagerRegistry $managerRegistry)
    {
        $this->mercureHub = $mercureHub;
        $this->managerRegistry = managerRegistry;
    }

    public function __invoke(PressureMessage $message)
    {
        try {
            $graphId = $message->getGraphId();
            $lastElapsedTime = $message->getLastElapsedTime();
            
            $em = $this->managerRegistry->getManager();

            $storedData = $em->getRepository(Pressure::class)->findLastRecordsForGraph($graphId, $lastElapsedTime);
            
            /**
             Set the data source for the pressure graph to a specific format from $toredData
            **/
            $formatedChartData = [];
                **....**
            

            $update = new Update(
                    sprintf('realtime-notif/pressure/%s', $graphId),
                    \json_encode($formatedChartData),
                    true
            );

            $this->mercureHub->publish($update);
        } catch (\Exception $exc) {
            
        }
    }
}

The problem for me is I don't know how to differentiate on the client side if the data received from the Mercure hub is from temperature topic or pressure topic in the message event of EventSource object.

<script type="text/javascript">
                $(document).ready(function () {
                    /**Create two graph on page ready **/
                    let temperatureGraphObject = createTemperatureGraph(canvasTemperaturaGraph);
                    let pressureGRaphObject = createPressureGraph(canvasPressureGraph);
                    
                    /** 
                    I have two function updateTemperatureGraph(temperatureGraphObject, newTemperaturaData) and updatePressureGraph(pressureGraphObject, newPresureData)
                    **/
                    
                    /**Subscribe client to topics for data updates **/
                    {% set topics = ['realtime-notif/temperature/'~temperatureSensorId, 'realtime-notif/pressure/'~pressureSensorId] %}

                    const eventSource = new EventSource("{{ mercure(topics, { subscribe:topics})|escape('js')}}", {withCredentials: true});

                    eventSource.onopen = function () {
                        console.log('New socket connection!');
                    };

                    eventSource.onmessage = function (e) {
                        console.log('New data received');
                        var data = JSON.parse(e.data);
                        
                        /** 
                        The problem is here, how differentiate the topics data to call updateTemperaturaGraph(temperatureGraphObject, data) or  updatePressureGraph(pressureGraphObject, data)
                        **/                     
                    };

                    eventSource.onerror = function () {
                        console.log('Socket connection lost!');
                    };
                });
            </script>

So, how differentiate the topics data to call updateTemperaturaGraph(temperatureGraphObject, data) or updatePressureGraph(pressureGraphObject, data) into onmessage event?

If I subscribe the client to only one topic all data received will be of kind of the topic graph, and of course the graph is updated correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南冥有猫 2025-01-26 11:14:13

该解决方案设置为DE type 属性,用于您要在MessageHandler相关类中在Mercure Hub中发布的更新类构造函数。因此,对于与温度通知相关的消息,我们将设置type attribute ='demperibupdate',对于与压力通知有关的消息,我们将设置类型 attribute ='压力update'。

__ Indoke wevermessageHandler

public function __invoke(TemperatureMessage $message)
{
    try {
        $graphId = $message->getGraphId();
        
        // Collect the data for the update
        $data = [/* ... */];

        $update = new Update(
            sprintf('realtime-notif/temperature/%s', $graphId),
            \json_encode($data),
            true,
            null,
            'temperatureUpdate'
        );

        $this->mercureHub->publish($update);
    } catch (\Exception $exc) {
        
    }
}

__ Invoke函数 pasterremessagehandler :

public function __invoke(PressureMessage $message)
{
    try {
        $graphId = $message->getGraphId();

        // Collect the data for the update
        $data = [/* ... */];

        $update = new Update(
            sprintf('realtime-notif/pressure/%s', $graphId),
            \json_encode($data),
            true,
            null,
            'pressureUpdate'
        );

        $this->mercureHub->publish($update);
    } catch (\Exception $exc) {
        
    }
}

在客户端上,创建两个eventsource对象的新eventlisteners,名称等于创建的新类型。每个新的侦听器都会处理Mercure Hub中发布的相关消息类型:

<script type="text/javascript">
    $(document).ready(function () {
        /**Create two graph on page ready **/
        let temperatureGraphObject = createTemperatureGraph(canvasTemperaturaGraph);
        let pressureGRaphObject = createPressureGraph(canvasPressureGraph);
        
        /** 
        I have two function updateTemperatureGraph(temperatureGraphObject, newTemperaturaData) and updatePressureGraph(pressureGraphObject, newPresureData)
        **/
        
        /**Subscribe client to topics for data updates **/
        {% set topics = ['realtime-notif/temperature/'~temperatureSensorId, 'realtime-notif/pressure/'~pressureSensorId] %}

        const eventSource = new EventSource("{{ mercure(topics, { subscribe:topics})|escape('js')}}", {withCredentials: true});

        eventSource.onopen = function () {
            console.log('New socket connection!');
        };

        eventSource.addEventListener("temperaturaUpdate", function (e) {
            let parsedData = null;
            try {
                parsedData = JSON.parse(e.data);
            } catch (error) {
                console.log(error);
            }
            
            if (parsedData) {
                updateTemperatureGraph(temperatureGraphObject, parsedData);
            }
        }, false);
        
        eventSource.addEventListener("pressureUpdate", function (e) {
            let parsedData = null;
            try {
                parsedData = JSON.parse(e.data);
            } catch (error) {
                console.log(error);
            }
            
            if (parsedData) {
                updatePressureGraph(pressureGraphObject, parsedData);
            }
        }, false);

        eventSource.onerror = function () {
            console.log('Socket connection lost!');
        };
    });
</script>

通过这种方式,Mercure Hub发布了分类的消息,每个EventListener都将负责按照订阅的顺序处理相应的消息处理相应的消息客户,无论其订阅的主题如何。

The solution is set de type attribute for Update class constructor that you want to publish in your Mercure hub from the MessageHandler related class. So, for the messages related to temperature notification we will set the type attribute = 'temperatureUpdate', and for the message related to pressure notification we will set the type attribute = 'pressureUpdate'.

The __invoke function on TemperatureMessageHandler:

public function __invoke(TemperatureMessage $message)
{
    try {
        $graphId = $message->getGraphId();
        
        // Collect the data for the update
        $data = [/* ... */];

        $update = new Update(
            sprintf('realtime-notif/temperature/%s', $graphId),
            \json_encode($data),
            true,
            null,
            'temperatureUpdate'
        );

        $this->mercureHub->publish($update);
    } catch (\Exception $exc) {
        
    }
}

The __invoke function on PressureMessageHandler:

public function __invoke(PressureMessage $message)
{
    try {
        $graphId = $message->getGraphId();

        // Collect the data for the update
        $data = [/* ... */];

        $update = new Update(
            sprintf('realtime-notif/pressure/%s', $graphId),
            \json_encode($data),
            true,
            null,
            'pressureUpdate'
        );

        $this->mercureHub->publish($update);
    } catch (\Exception $exc) {
        
    }
}

On the client side, is mandatory to create two new EventListeners for the EventSource object, with the name equals to the new types created. Every one new listener will treat the related messages types published in the Mercure hub:

<script type="text/javascript">
    $(document).ready(function () {
        /**Create two graph on page ready **/
        let temperatureGraphObject = createTemperatureGraph(canvasTemperaturaGraph);
        let pressureGRaphObject = createPressureGraph(canvasPressureGraph);
        
        /** 
        I have two function updateTemperatureGraph(temperatureGraphObject, newTemperaturaData) and updatePressureGraph(pressureGraphObject, newPresureData)
        **/
        
        /**Subscribe client to topics for data updates **/
        {% set topics = ['realtime-notif/temperature/'~temperatureSensorId, 'realtime-notif/pressure/'~pressureSensorId] %}

        const eventSource = new EventSource("{{ mercure(topics, { subscribe:topics})|escape('js')}}", {withCredentials: true});

        eventSource.onopen = function () {
            console.log('New socket connection!');
        };

        eventSource.addEventListener("temperaturaUpdate", function (e) {
            let parsedData = null;
            try {
                parsedData = JSON.parse(e.data);
            } catch (error) {
                console.log(error);
            }
            
            if (parsedData) {
                updateTemperatureGraph(temperatureGraphObject, parsedData);
            }
        }, false);
        
        eventSource.addEventListener("pressureUpdate", function (e) {
            let parsedData = null;
            try {
                parsedData = JSON.parse(e.data);
            } catch (error) {
                console.log(error);
            }
            
            if (parsedData) {
                updatePressureGraph(pressureGraphObject, parsedData);
            }
        }, false);

        eventSource.onerror = function () {
            console.log('Socket connection lost!');
        };
    });
</script>

In this way, the Mercure hub publishes the classified messages, and each EventListener will be in charge of processing the corresponding message in the order in which it arrives at the subscribed client, regardless of the topics to which it is subscribed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文