You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试基于Sinatra的Server-Sent Events(SSE)聊天应用?

测试Sinatra Server-Sent Events(SSE)聊天应用的方法

首先先把你没写完的SSE核心代码补全,这样我们才能正常测试功能(毕竟你的stream块里的逻辑还没写完):

完整的Sinatra应用代码(保存为app.rb):

require 'sinatra'
require 'json'

class App < Sinatra::Base
  enable :logging
  set :server, :thin
  set :public_folder, File.dirname(__FILE__) + '/assets'
  set :views, File.dirname(__FILE__) + '/views'

  # 保存所有活跃的SSE连接
  connections = []

  get '/chat' do
    erb :chat
  end

  get '/stream' do
    content_type "text/event-stream"
    stream(:keep_open) do |out|
      # 新增连接加入列表
      connections.push(out)
      # 连接关闭时从列表移除
      out.callback { connections.delete(out) }
      out.errback { connections.delete(out) }
    end
  end

  # 接收客户端发送的消息,推送给所有连接
  post '/message' do
    message = JSON.parse(request.body.read)
    connections.each do |conn|
      conn << "data: #{JSON.generate(message)}\n\n"
    end
    status 200
  end
end

然后创建views/chat.erb前端页面,用来和后端交互:

<!DOCTYPE html>
<html>
<head>
  <title>SSE Chat Demo</title>
</head>
<body>
  <h2>聊天窗口</h2>
  <div id="messages" style="height: 300px; border: 1px solid #ccc; padding: 10px; overflow-y: auto;"></div>
  <div style="margin-top: 10px;">
    <input type="text" id="msgInput" placeholder="输入消息..." style="width: 300px;">
    <button onclick="sendMsg()">发送</button>
  </div>

  <script>
    // 建立SSE连接
    const eventSource = new EventSource('/stream');
    const messagesDiv = document.getElementById('messages');
    const msgInput = document.getElementById('msgInput');

    // 接收SSE推送的消息
    eventSource.onmessage = function(e) {
      const msg = JSON.parse(e.data);
      const msgElement = document.createElement('p');
      msgElement.textContent = msg.text;
      messagesDiv.appendChild(msgElement);
      // 滚动到最新消息
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    };

    // 发送消息到后端
    function sendMsg() {
      const text = msgInput.value.trim();
      if (!text) return;
      
      fetch('/message', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: text })
      });
      
      msgInput.value = '';
    }

    // 监听回车发送
    msgInput.addEventListener('keydown', function(e) {
      if (e.key === 'Enter') sendMsg();
    });
  </script>
</body>
</html>

接下来是具体的测试方法:

1. 浏览器手动测试(最直观的验证方式)

这是最快验证SSE实时推送的方法:

  • 先安装依赖:gem install sinatra thin
  • 启动服务器:ruby app.rb
  • 打开2个及以上浏览器窗口,访问 http://localhost:4567/chat
  • 在任意一个窗口发送消息,其他窗口应该能实时收到消息,这就说明SSE的连接和推送功能正常工作。

2. 命令行工具测试(无需前端,直接验证后端接口)

如果你不想依赖前端页面,可以用curl直接测试:

  • 测试SSE连接:打开一个终端,运行以下命令(-N参数禁用curl的缓冲,实时输出内容):
    curl -N http://localhost:4567/stream
    
    这个命令会保持长连接,等待服务器推送消息。
  • 发送测试消息:打开另一个终端,运行POST请求模拟客户端发送消息:
    curl -X POST -H "Content-Type: application/json" -d '{"text":"Hello from curl!"}' http://localhost:4567/message
    
    此时第一个终端的curl应该会立即输出:
    data: {"text":"Hello from curl!"}
    
    这就说明SSE的接收和推送逻辑是对的。

3. 自动化测试脚本(适合持续集成或功能回归测试)

如果需要写自动化测试,可以用RSpec+Faraday来实现:

  • 安装测试依赖:gem install rspec faraday rack-test
  • 创建spec/app_spec.rb测试文件:
    require 'rspec'
    require 'faraday'
    require 'rack/test'
    require_relative '../app'
    
    RSpec.describe App do
      include Rack::Test::Methods
    
      def app
        App
      end
    
      it 'successfully pushes messages via SSE to connected clients' do
        # 启动线程保持SSE连接,收集收到的消息
        received_messages = []
        sse_thread = Thread.new do
          conn = Faraday.new(url: 'http://localhost:4567') do |f|
            f.adapter :net_http
          end
          conn.get('/stream') do |req|
            req.options.timeout = 10
            # 处理流式响应
            req.on_data do |chunk, _|
              received_messages << chunk.strip if chunk.start_with?('data:')
            end
          end
        end
    
        # 发送测试消息
        post '/message', { text: 'Automated test message' }.to_json, 'CONTENT_TYPE' => 'application/json'
        expect(last_response.status).to eq(200)
    
        # 等待消息被接收
        sleep 1
        expect(received_messages).to include('data: {"text":"Automated test message"}')
    
        # 终止SSE连接线程
        sse_thread.kill
      end
    end
    
  • 运行测试:rspec spec/app_spec.rb,如果测试通过,说明SSE功能稳定。

内容的提问来源于stack exchange,提问作者Julio Farah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:43:54