Using eventsource to push page messages

Time:2021-8-8

I was thinking about how to use our automatic deployment tool essay some time agohttps://github.com/SohuTech/e…_ Package a layer of Web shell, so that you don’t have to hit many commands every time you distribute the version. You only need to click a few buttons, which can also reduce the mental burden of distributing the version. When doing this, the main problem is how to better output the results originally output on terminal to the web interface in real time. Finally, I found eventsource. Except that IE browser does not support it, other browsers have built-in this object, which can well meet my needs.

What is eventsource

Specifically, what is server sent events (SSE)? Wikipedia is introduced as follows:

Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is standardized as part of HTML5[1] by the W3C.

SSE is a technology that enables browsers to automatically receive server-side updates through HTTP connection. SSE eventsource interface is formulated by W3C as a part of HTML5.
You can see this link in the W3C section:EventSource

The function of this technology is to complete one-way message transmission from server to client (browser). So we can use this to push. However, it should be noted that ie does not support this technology.

How to use eventsource

We know the function of eventsource above, so how to use it?

Send events from the HTML 5 server herehttp://www.w3school.com.cn/ht…_ We can simply see its usage. Here I’m using Django to demonstrate. I won’t say much about the specific use of Django. The version of Django I use is 1.6.7.

First, write the page. You can write it simply:
.. code:: html

<html>
<head>
<title>EventSource-Dango-Demo by the5fire</title>
<script>
    var source=new EventSource("/eventsource/");
    source.onmessage=function(event)
    {
        document.getElementById("result").innerHTML+=event.data + "<br />";
    };
</script>
</head>
<body>
<div id="result">
</div>
</body>
</html>

When the page is loaded, the above JS script will be executed. The script will initialize an eventroute, listen on the URI / eventsource /, and then set how to handle the message received by the souce object.

The page is very simple. Let’s look at the Django code. Start project eventsource via django-admin.py_ Django create a Django project. The structure is as follows:

.
└── eventsource_django

├── eventsource_django
│   ├── __init__.py
│   ├── settings.py
│   ├── templates
│   │   └── index.html
│   ├── urls.py
│   └── wsgi.py
└── manage.py

3 directories, 6 files
Put the above HTML code into index.html, and then open the urls.py file and change it to the following code:

.. code:: python

from django.conf.urls import patterns

from django.views.generic import TemplateView


urlpatterns = patterns(
    '',
    (r'^$', TemplateView.as_view(template_name="index.html")),
)

After starting Django server in this way, the home page is the code we wrote. At this time, you start the project: Python manage.py runserver. When the browser accesses localhost: 8000, it will find that the terminal will receive a request for / eventsource /, and the result is 404. Now deal with the request to show how the server can send messages to the browser.

First, create a view in the eventsource_ Under Django, the same level directory as urls.py( This is the way to write the demonstration, which will not be written in the formal project)

The code of views.py is as follows:

.. code:: python

# coding:utf-8

import time

from django.http import StreamingHttpResponse
from django.utils.timezone import now


def eventsource(request):
    response = StreamingHttpResponse(stream_generator(), content_type="text/event-stream")
    response['Cache-Control'] = 'no-cache'
    return response


def stream_generator():
    while True:
        #Send event data
        # yield 'event: date\ndata: %s\n\n' % str(now())

        #Send data
        yield u'data: %s\n\n' % str(now())
        time.sleep(2)

The streaminghttpresponse can be simply understood as a streaming response, and its content parameters need to be a generator. Therefore, a generator is implemented below with yield, which returns’ data: time \ n \ n ‘every two seconds. This is a specification of source send event. In addition, it can also set the event type, such as the code I commented out. The processing method of the corresponding event is different from that of a simple message. JS has to write:

source = EventSource('/eventsource/')
source.addEventListener("date", function (event) {
    console.log(event.data);
});

In this way, you can filter the events you need.

After writing the code of views.py, urls.py needs to be configured as follows:

.. code:: python

from django.conf.urls import patterns

from django.views.generic import TemplateView

from .views import eventsource


urlpatterns = patterns(
    '',
    (r'^eventsource/$', eventsource),
    (r'^$', TemplateView.as_view(template_name="index.html")),
)

Then run the program again, refresh the page, and you can see the continuous output time of the page. After this logic runs through, imagine that if you don’t directly give a string at the yield and then take out the data from a queue, can you realize the message notification of the page?

summary

It’s getting late. Let’s summarize briefly. This technology is much simpler than websocket, but SSE only transmits data one way from the server to the client, so it is somewhat different from the application scenario of websocket.

SSE is also very simple to use. For example, in our scenario, redirect the output of terminal to the web interface.

Although ie itself does not support it, it can be compatible through eventsource.js.

resources

My demo source code:https://github.com/the5fire/p…
https://github.com/niwibe/dja…
http://www.w3.org/TR/eventsou…
http://www.w3school.com.cn/ht…