如何测试基于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应该会立即输出:curl -X POST -H "Content-Type: application/json" -d '{"text":"Hello from curl!"}' http://localhost:4567/message
这就说明SSE的接收和推送逻辑是对的。data: {"text":"Hello from curl!"}
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
相关产品推荐
相关产品推荐

