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

客户端与服务端WebSocket连接异常问题排查求助

问题分析与修复方案

核心问题

你的后端用Boost.Asio实现的是普通TCP套接字服务,但前端尝试用WebSocket协议连接,两者协议不匹配,导致连接无法建立,因此出现「WebSocket is not open yet. Message not sent」错误。WebSocket是基于HTTP的升级协议,并非原生TCP,直接连接普通TCP端口必然失败。

修复方案

方案一:后端改为WebSocket服务器(推荐)

使用支持WebSocket的库重构后端,你已引入的cpprestsdk(Casablanca)本身支持WebSocket服务,以下是简化实现示例:

#include <cpprest/ws_client.h>
#include <cpprest/ws_listener.h>
#include <vector>
#include <mutex>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/json.h>

using namespace web;
using namespace web::websockets::server;
using namespace web::http;
using namespace web::http::client;

std::vector<websocket_session> g_clients;
std::mutex g_clients_mutex;

std::wstring chatWithGPT3(const std::wstring& userMessage) {
    const utility::string_t apiKey = U("你的API密钥");
    web::http::client::http_client client(U("https://api.openai.com/v1/completions"));
    web::http::http_request request(web::http::methods::POST);

    request.headers().set_content_type(U("application/json"));
    request.headers().add(U("Authorization"), U("Bearer ") + apiKey);

    web::json::value body;
    body[U("model")] = web::json::value::string(U("davinci-002"));          
    body[U("prompt")] = web::json::value::string(userMessage);
    body[U("max_tokens")] = web::json::value(50);

    request.set_body(body);

    try {
        web::http::http_response response = client.request(request).get();
        if (response.status_code() == web::http::status_codes::OK) {
            return response.to_string();
        } else {
            std::cerr << "ChatGPT API错误: " << response.status_code() << std::endl;
            return L"处理请求时出错";
        }
    } catch (const std::exception& e) {
        std::cerr << "API请求异常: " << e.what() << std::endl;
        return L"处理请求时出错";
    }
}

void on_message(websocket_session session, websocket_incoming_message msg) {
    auto user_msg = msg.extract_string().get();
    std::wstring gpt_response = chatWithGPT3(utility::conversions::to_wstring_t(user_msg));
    
    std::lock_guard<std::mutex> lock(g_clients_mutex);
    for (auto& client : g_clients) {
        if (client != session) {
            websocket_outgoing_message out_msg;
            out_msg.set_string(utility::conversions::to_string_t(L"ChatGPT: " + gpt_response));
            client.send(out_msg).wait();
        }
    }
}

void on_open(websocket_session session) {
    std::lock_guard<std::mutex> lock(g_clients_mutex);
    g_clients.push_back(session);
    std::cout << "新客户端连接" << std::endl;
}

void on_close(websocket_session session) {
    std::lock_guard<std::mutex> lock(g_clients_mutex);
    g_clients.erase(std::remove(g_clients.begin(), g_clients.end(), session), g_clients.end());
    std::cout << "客户端断开连接" << std::endl;
}

int main() {
    try {
        websocket_listener listener(U("ws://localhost:7000"));
        
        listener.set_message_handler(&on_message);
        listener.set_open_handler(&on_open);
        listener.set_close_handler(&on_close);
        
        listener.open().wait();
        std::cout << "WebSocket服务器运行在7000端口..." << std::endl;
        
        std::string line;
        std::getline(std::cin, line);
        
        listener.close().wait();
    } catch (const std::exception& e) {
        std::cerr << "服务器启动失败: " << e.what() << std::endl;
    }
    return 0;
}

方案二:前端改为普通TCP socket(不推荐)

浏览器没有原生普通TCP套接字API(WebRTC DataChannel实现复杂),因此该方案不具备可行性。

前端代码调整

保留原有WebSocket连接逻辑,调整sendMessage触发方式(避免在连接打开时自动发送空消息),添加触发按钮:

<input type="text" id="chat-input" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
<div id="chat-output"></div>

JavaScript代码无需大改,仅确保sendMessage由用户操作触发即可。

额外检查项

  • 先启动后端服务器,再打开前端页面,查看控制台是否打印「WebSocket connection opened」,确认连接建立。
  • 用telnet localhost 7000测试端口连通性,若不通则检查后端是否正确监听7000端口、端口是否被占用。
  • ChatGPT API调用的同步等待(get())会阻塞服务器,高并发场景建议改用异步回调优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:45:54