showliuzp 2025-10-18 12:10 采纳率: 84.3%
浏览 7
已结题

golang websocket输出错误消息到前端

 
//聊天窗口
func WsChat(w http.ResponseWriter, r *http.Request) {
    var (
        conn            *websocket.Conn
        err             error      
        streamerids     string
        )
 
 
 
    //从head头里取出主播id,校验是否存在主播,建立websocket连接需要以此主播为key
    streamerids   = (*r).Header.Get("streamer_id")
    streamer_id,_:= strconv.ParseInt(streamerids,10,64)
 
    user_info, err:=ws_chat_obj.WsChatStreamerChkExists(streamer_id)
    fmt.Printf("token_data:%+v,streamer_id:%+v,user_info:%+v\n",token_data,streamer_id,user_info)
    if err != nil{
        w.WriteHeader(http.StatusOK)
        resp,_ := json.Marshal(response.Response{Code:0,Msg:"主播不存在或者状态异常"})
        w.Write([]byte(resp))
        return
    }
 
    if user_info.Id < 1 || user_info.Status != types.NORMAL{
        w.WriteHeader(http.StatusOK)
        resp,_ := json.Marshal(response.Response{Code:0,Msg:"主播不存在或者状态异常"})
        w.Write([]byte(resp))
        return
    }
}
 
 
我写了一段websocket代码,在建立连接前,需要对数据进行验证,从head头获取一个streamer_id参数,校验不通过输出状态码为200并吐出json,即使文本也显示不出来,但在postman里,http状态码显示出来了,吐出的json或文本没有显示出来,这是怎么回事?

  • 写回答

5条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-10-18 13:07
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:别让生活的琐碎,磨掉你对美好的向往。
    .

    根据你提供的代码,我发现了问题所在。当你使用WebSocket连接时,客户端期望的是WebSocket握手协议,但你返回的是普通的HTTP响应,这导致了连接失败。

    问题分析

    1. WebSocket握手过程:WebSocket连接建立前会有一个HTTP握手过程
    2. 响应格式不匹配:客户端期望WebSocket协议响应,但你返回了普通HTTP JSON响应
    3. 连接未建立:由于握手失败,后续的数据传输无法进行

    解决方案

    方案1:在WebSocket升级前进行验证(推荐)

    func WsChat(w http.ResponseWriter, r *http.Request) {
        // 在WebSocket升级前进行验证
        streamerids := r.Header.Get("streamer_id")
        streamer_id, err := strconv.ParseInt(streamerids, 10, 64)
        if err != nil {
            sendErrorResponse(w, "无效的主播ID")
            return
        }
    
    
        user_info, err := ws_chat_obj.WsChatStreamerChkExists(streamer_id)
        if err != nil || user_info.Id < 1 || user_info.Status != types.NORMAL {
            sendErrorResponse(w, "主播不存在或者状态异常")
            return
        }
    
    
        // 验证通过后再升级为WebSocket连接
        conn, err := websocket.Upgrade(w, r, nil, 1024, 1024)
        if err != nil {
            log.Printf("WebSocket升级失败: %v", err)
            return
        }
        
        // 后续的WebSocket处理逻辑...
    }
    
    
    func sendErrorResponse(w http.ResponseWriter, message string) {
        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusOK)
        resp, _ := json.Marshal(response.Response{
            Code: 0,
            Msg:  message,
        })
        w.Write(resp)
    }
    

    方案2:使用WebSocket协议发送错误消息

    如果必须在WebSocket连接建立后发送错误,可以这样做:

    func WsChat(w http.ResponseWriter, r *http.Request) {
        conn, err := websocket.Upgrade(w, r, nil, 1024, 1024)
        if err != nil {
            log.Printf("WebSocket升级失败: %v", err)
            return
        }
        defer conn.Close()
    
    
        // 验证逻辑
        streamerids := r.Header.Get("streamer_id")
        streamer_id, err := strconv.ParseInt(streamerids, 10, 64)
        if err != nil {
            sendWsError(conn, "无效的主播ID")
            return
        }
    
    
        user_info, err := ws_chat_obj.WsChatStreamerChkExists(streamer_id)
        if err != nil || user_info.Id < 1 || user_info.Status != types.NORMAL {
            sendWsError(conn, "主播不存在或者状态异常")
            return
        }
    
    
        // 正常处理逻辑...
    }
    
    
    func sendWsError(conn *websocket.Conn, message string) {
        errorResp := response.Response{
            Code: 0,
            Msg:  message,
        }
        if err := conn.WriteJSON(errorResp); err != nil {
            log.Printf("发送WebSocket错误消息失败: %v", err)
        }
    }
    

    方案3:客户端处理改进

    确保客户端正确处理连接失败的情况:

    // 前端JavaScript示例
    function connectWebSocket() {
        const ws = new WebSocket('ws://your-server/ws-chat');
        
        ws.onopen = function(event) {
            console.log('WebSocket连接已建立');
        };
        
        ws.onmessage = function(event) {
            const data = JSON.parse(event.data);
            if (data.Code === 0) {
                // 处理错误消息
                console.error('错误:', data.Msg);
                // 显示错误给用户
                showErrorMessage(data.Msg);
            } else {
                // 正常消息处理
                handleChatMessage(data);
            }
        };
        
        ws.onerror = function(error) {
            console.error('WebSocket错误:', error);
            // 处理连接错误
            showErrorMessage('连接失败,请重试');
        };
        
        ws.onclose = function(event) {
            console.log('WebSocket连接已关闭');
        };
    }
    

    关键点总结

    1. 验证时机:在WebSocket升级前完成所有验证
    2. 响应格式:验证失败时返回标准HTTP响应,而不是WebSocket消息
    3. 错误处理:客户端需要处理连接失败和服务器返回的错误消息

    建议使用方案1,因为它在握手阶段就完成验证,更符合HTTP/WebSocket协议规范。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 10月26日
  • 已采纳回答 10月18日
  • 创建了问题 10月18日