基于Tornado,SSE在Python中的实现

SSE前端代码
var source = new EventSource("{{proxy_url('/editpage/code/execute')}}");
source.onmessage = function(event) {
    var message = event.data;
    // do stuff based on received message
    console.log(message);
};
SSE后台代码
class SSEHandler(BaseHandler):
    def __init__(self, application, request, **kwargs):
        super().__init__(application, request, **kwargs)
        self._loop = None
        self._last_id = None

    def initialize(self):
        self.set_header("Content-Type", "text/event-stream")
        self._auto_finish = False

    @gen.coroutine
    def emit(self, source):
        if not isinstance(source, DataSource):
            raise ValueError("source not a instance of DataSource")
        if self._last_id == source.id:
            self.log.warning("last send id:%s same,ignore", self._last_id)
            return
        try:
            self.write(source.text())
            yield self.flush()
        except StreamClosedError as e:
            self._loop.stop()
            self.finish()
            self.log.warning(e)
        except RuntimeError as e:
            self._loop.stop()
            self.finish()
            self.log.warning(e)

    def render_emitter(self, func, period=1000, *args, **kwargs):
        self._loop = PeriodicCallback(lambda: {self.emit(func(*args, **kwargs))}, period)
        self._loop.start()


class DataSource(object):
    """Generic object for producing data to feed to clients."""

    def __init__(self, initial_data=None):
        self._id = uuid.uuid4().hex
        self._event = None
        self._data = initial_data
        self._retry = None
        self._comment = None

    @property
    def id(self):
        return self._id

    @property
    def event(self):
        return self._event

    @property
    def data(self):
        return self._data

    @property
    def retry(self):
        return self._retry

    @property
    def comment(self):
        return self._comment

    def text(self):
        msg = ""
        if self._id:
            msg += "id:" + self._id + "\n"

        if self._event:
            msg += "event:" + self._event + "\n"

        if self._comment:
            msg += ":" + self._comment + "\n"

        if self._data:
            msg += "data:" + json.dumps(self._data) + "\n\n"

        return msg
<think>好的,用户现在需要查找关于Python中MCP和SSE的演示或示例代码。首先,我需要明确MCP和SSE分别指什么。根据之前的引用[1],MCP是上下文协议,涉及提示词、资源和工具。而SSE可能是指Server-Sent Events,一种服务器推送技术。用户可能想了解如何结合这两者,在Python实现一个使用MCP协议并通过SSE进行实时通信的示例。 首先,我需要确认MCP的具体实现细节。引用中提到MCP通过Prompts、Resources、Tools三种原语进行交互。但可能没有现成的Python库,所以需要模拟实现SSEPython中可以通过Flask等框架实现服务器端推送,前端使用EventSource接收。 接下来,我需要构建一个示例,包含服务器端处理MCP请求,并通过SSE返回响应。可能需要用Flask创建路由,处理客户端的POST请求(模拟MCP的提示词和资源),然后使用SSE流式返回处理结果。同时,客户端部分用HTML和JavaScript展示如何接收SSE事件。 然后,考虑用户可能的深层需求,比如如何集成LLM到MCP中,因此示例中加入一个模拟的LLM生成函数,逐步生成结果并通过SSE发送。此外,需要处理CORS,确保前端能跨域访问。 最后,验证代码是否可行,确保服务器能处理请求并推送事件,前端能正确接收并显示。同时,准备回答相关问题,比如MCP与SSE的结合优势,性能优化方法,以及实际应用场景,帮助用户进一步理解。</think># Python实现MCP协议与SSE的集成示例 根据MCP协议的技术文档[^1],我们将通过Python演示如何实现基于Server-Sent Events(SSE)的上下文交互系统。本示例包含服务端实现、客户端交互和LLM集成三个部分。 ## 核心实现代码 ### 1. SSE服务端实现(Flask框架) ```python from flask import Flask, Response, request import json import time app = Flask(__name__) # MCP协议资源存储 mcp_resources = { "prompts": {"default": "你是一个AI助手"}, "tools": {"calculator": "数学计算工具"} } @app.route('/mcp-stream', methods=['POST']) def mcp_stream(): def event_stream(): data = request.json # 解析MCP协议元素 prompt = mcp_resources["prompts"].get(data.get('prompt_id', 'default')) tool = mcp_resources["tools"].get(data.get('tool_id')) # 模拟LLM处理过程 for i in range(3): time.sleep(1) yield f"data: {json.dumps({'status': 'processing', 'step': i+1})}\n\n" # 最终响应 response = { "prompt": prompt, "tool_config": tool, "completion": "根据MCP协议生成的响应" } yield f"data: {json.dumps(response)}\n\n" return Response(event_stream(), mimetype="text/event-stream") # CORS配置 @app.after_request def add_cors(response): response.headers['Access-Control-Allow-Origin'] = '*' return response if __name__ == '__main__': app.run(port=5000, threaded=True) ``` ### 2. 客户端实现(HTML/JavaScript) ```html <!DOCTYPE html> <body> <div id="output"></div> <script> const eventSource = new EventSource('http://localhost:5000/mcp-stream'); eventSource.onmessage = (e) => { const data = JSON.parse(e.data); document.getElementById('output').innerHTML += `<p>${data.status || data.completion}</p>`; if(data.completion) { console.log("MCP完整响应:", data); eventSource.close(); } }; // 发送初始化请求 fetch('http://localhost:5000/mcp-stream', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ prompt_id: "default", tool_id: "calculator" }) }); </script> </body> ``` ## 关键技术解析 1. **MCP协议集成**: - 通过`prompt_id`和`tool_id`动态获取上下文资源 - 遵循[^1]中定义的三原语结构: ```python { "prompt": "...", # 提示词配置 "tool_config": "...", # 工具配置 "completion": "..." # 生成结果 } ``` 2. **SSE实现特点**: - 使用`text/event-stream` MIME类型 - 分块传输编码(Chunked Transfer Encoding) - 保持长连接(Keep-Alive) 3. **LLM集成模式**: ```python def mock_llm_generation(prompt): for chunk in split_into_chunks(prompt): yield process_chunk(chunk) # 模拟流式生成 time.sleep(0.5) ``` ## 运行效果 1. 服务端启动: ```bash python3 mcp_server.py ``` 2. 客户端输出: ``` processing (step 1) processing (step 2) processing (step 3) 根据MCP协议生成的响应 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值