当前位置: 代码网 > it编程>前端脚本>Python > 使用Python和Go实现服务器发送事件(SSE)

使用Python和Go实现服务器发送事件(SSE)

2024年11月26日 Python 我要评论
为什么选择sse?服务器发送事件是html5规范的一部分,专门用于将事件从服务器推送到客户端。它的简单性、自动重新连接和事件跟踪功能使其非常适合数据流的场景。在单向数据流情况下,sse表现尤其出色。概

为什么选择sse?

服务器发送事件是html5规范的一部分,专门用于将事件从服务器推送到客户端。它的简单性、自动重新连接和事件跟踪功能使其非常适合数据流的场景。在单向数据流情况下,sse表现尤其出色。

概述

sse是一种服务器向浏览器实时推送消息的技术。它是html5规范的一部分,主要涉及:

  • 通信协议:使用http。
  • 事件对象:在浏览器端可用。

websockets也是一种实时通信技术,但它们有不同之处:

ssewebsockets
基于http基于tcp
单向(服务器到客户端)全双工(双向)
轻量级和简单更复杂的
内置重新连接和消息跟踪需要手动实现这些功能
文本或base64和gzip压缩的二进制文件支持各种数据类型
支持自定义事件类型不支持自定义事件类型
http/1.1或http/2限制连接数量无限连接

服务器实现

协议实现

本质上,浏览器发起一个http请求,服务器用http状态进行响应,包括以下标头:

content-type: text/event-stream
cache-control: no-cache
connection: keep-alive

sse指定事件流的mime类型必须为 text/event-stream ,浏览器不应该缓存数据,并且连接应该是持久的( keep-alive )。

消息格式

事件流是使用utf-8编码的文本或base64编码的二进制消息,并使用gzip压缩。每条消息由一行或多行字段组成,格式为 field-name : field-value 。每个字段以 \n 结尾。以冒号开头的行是注释,会被浏览器忽略。每个推送可以由多个消息组成,以空行分隔( \n\n )。

关键字段包括:

  • event :事件类型。
  • id :事件id,浏览器跟踪最后接收到的事件用来重新连接服务。
  • retry :浏览器在连接失败后重新尝试连接所需的等待时间(ms)。
  • data :消息数据。

示例:python实现sse

from flask import flask, response

app = flask(__name__)


@app.route('/events')
def sse_handler():
    def generate():
        paragraph = [
            "hello, this is an example of a continuous text output.",
            "it contains multiple sentences, each of which will be sent to the client as an event.",
            "this is to simulate the functionality of server-sent events (sse).",
            "we can use this method to push real-time updates.",
            "end of sample text, thank you!",
        ]

        for sentence in paragraph:
            yield f"data: {sentence}\n\n"

            import time
            time.sleep(1)

    return response(generate(), mimetype='text/event-stream')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081, debug=true)

示例:go实现sse

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    http.handlefunc("/events", ssehandler)

    fmt.println("starting server on :8080")
    if err := http.listenandserve(":8080", nil); err != nil {
        log.fatalf("server error: %v", err)
    }
}

func ssehandler(w http.responsewriter, r *http.request) {
    flusher, ok := w.(http.flusher)
    if !ok {
        http.error(w, "streaming unsupported!", http.statusinternalservererror)
        return
    }

    w.header().set("content-type", "text/event-stream")
    w.header().set("cache-control", "no-cache")
    w.header().set("connection", "keep-alive")

    // change the output here to a specific text
    paragraph := []string{
        "hello, this is an example of a continuous text output.",
        "it contains multiple sentences, each of which will be sent to the client as an event.",
        "this is to simulate the functionality of server-sent events (sse).",
        "we can use this method to push real-time updates.",
        "end of sample text, thank you!",
    }

    for _, sentence := range paragraph {
        _, err := fmt.fprintf(w, "data: %s\n\n", sentence)
        if err != nil {
            return
        }
        flusher.flush()
        time.sleep(1 * time.second) // wait 1 second before sending the next piece of text
    }
}

浏览器api️

在客户端,javascript的 eventsource api允许您创建一个 eventsource 对象来侦听服务器发送的事件。一旦连接上,服务器就可以向浏览器发送事件消息。浏览器通过监听 onmessageonopenonerror 事件来处理这些消息。

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sse example 🌟</title>
</head>
<body>
    <h1>server-sent events example 🚀</h1>
    <div id="messages"></div>
    <script>
        window.onload = function() {
            if (typeof(eventsource) !== "undefined") {
                const eventsource = new eventsource('/events');

                eventsource.onmessage = function(event) {
                    const newelement = document.createelement("p");
                    newelement.textcontent = "message: " + event.data;

                    document.getelementbyid("messages").appendchild(newelement);
                };

                eventsource.onerror = function(event) {
                    console.error("error occurred: ", event);
                    const newelement = document.createelement("p");
                    newelement.textcontent = "an error occurred while connecting to the event source.";
                    document.getelementbyid("messages").appendchild(newelement);
                    eventsource.close(); 
                };
            } else {
                document.getelementbyid("messages").textcontent = "sorry, your browser does not support server-sent events...";
            }
        };
    </script>
</body>
</html>

sse调试

目前,许多流行的工具,如postman、insomnia、bruno和thunderclient缺乏对服务器发送事件sse的足够支持。在开发过程中,这种限制会让人非常沮丧。幸运的是,我最近遇到了echoapi,这个工具提供了出色的sse调试功能。这个发现极大地改善了我的工作流程,提高了效率和生产力。

如果您正在使用sse或进行api调试,我强烈建议您尝试一下echoapi。它可以彻底改变您的调试体验并简化您的开发工作。

示例:sse的echoapi客户端

在echoapi中,使用sse接口非常简单。只需输入url,填写相关参数,然后点击“发送”即可看到您的请求结果。

以上就是使用python和go实现服务器发送事件(sse)的详细内容,更多关于python go服务器发送事件的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com