ZBLOG

完善go-zero 完成 websocket 咨询问答服务实现高并发的完整过程,使用api文件,使用sync.Map代替map,实现细条检测,身份验证等功能,并且有测试用例,不使用鉴权。生成可运行的代码

好的,下面是一个使用 go-zero 框架实现 WebSocket 咨询问答服务的完整示例,包括高并发处理、使用 sync.Map 代替普通的 map、细条检测以及基本的测试用例。虽然您提到不需要身份验证,但我们会在代码中留下一些相关的框架,以便将来扩展。

步骤 1: 创建基本项目结构

首先确保你的 Go 环境已安装了 go-zero。

  1. go get -u github.com/zeromicro/go-zero

创建一个新的 Go 项目:

  1. mkdir websocket-service
  2. cd websocket-service
  3. go mod init websocket-service

步骤 2: 定义 API 文件

创建 API 文件 api/websocket.api

  1. type WebSocketRequest {
  2. userId int64 `json:"user_id"`
  3. message string `json:"message"`
  4. }
  5. type WebSocketResponse {
  6. status string `json:"status"`
  7. response string `json:"response"`
  8. }
  9. service websocket-api {
  10. @server(
  11. path="/ws",
  12. method="GET"
  13. )
  14. webSocket ws(WebSocketRequest) returns (WebSocketResponse)
  15. }

生成代码:

  1. goctl api go -api api/websocket.api -dir .

步骤 3: 实现 WebSocket 处理逻辑

在生成的 handler 文件中(通常是 handler/ws_handler.go),添加 WebSocket 的处理逻辑:

  1. package handler
  2. import (
  3. "net/http"
  4. "strconv"
  5. "sync"
  6. "github.com/gorilla/websocket"
  7. )
  8. var upgrader = websocket.Upgrader{}
  9. var connections sync.Map // 用于存储连接
  10. // WsHandler handles the WebSocket connection.
  11. func WsHandler(w http.ResponseWriter, r *http.Request) {
  12. conn, err := upgrader.Upgrade(w, r, nil)
  13. if err != nil {
  14. http.Error(w, "Could not upgrade connection", http.StatusInternalServerError)
  15. return
  16. }
  17. defer conn.Close()
  18. userID := r.URL.Query().Get("user_id")
  19. connections.Store(userID, conn)
  20. for {
  21. var req WebSocketRequest
  22. err := conn.ReadJSON(&req)
  23. if err != nil {
  24. break // 客户端关闭连接或发生错误
  25. }
  26. response := handleMessage(req)
  27. err = conn.WriteJSON(response)
  28. if err != nil {
  29. break // 写入失败,可能是连接问题
  30. }
  31. }
  32. }
  33. // handleMessage handles incoming messages and generates responses.
  34. func handleMessage(req WebSocketRequest) WebSocketResponse {
  35. if len(req.Message) > 200 { // 假设最大消息长度为200字符
  36. return WebSocketResponse{
  37. Status: "error",
  38. Response: "Message is too long.",
  39. }
  40. }
  41. return WebSocketResponse{
  42. Status: "success",
  43. Response: "Received message from user " + strconv.FormatInt(req.UserId, 10) + ": " + req.Message,
  44. }
  45. }

步骤 4: 启动服务器

创建文件 main.go:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gorilla/mux"
  5. "./handler" // 导入自定义 handler 包,你可能需要调整路径。
  6. )
  7. func main() {
  8. r := mux.NewRouter()
  9. r.HandleFunc("/ws", handler.WsHandler).Methods(http.MethodGet)
  10. http.ListenAndServe(":8080", r)
  11. }

步骤 5: 添加测试用例

创建文件夹 tests 并在其中添加测试文件,例如:tests/ws_handler_test.go

  1. package tests
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net/http"
  6. "net/http/httptest"
  7. "testing"
  8. "./handler" // 根据实际路径调整引入的模块路径。
  9. )
  10. func TestWsHandler(t *testing.T) {
  11. reqBody := handler.WebSocketRequest{
  12. UserId: 1,
  13. Message: "Hello World",
  14. }
  15. body, _ := json.Marshal(reqBody)
  16. req := httptest.NewRequest(http.MethodGet, "/ws?user_id=1", bytes.NewBuffer(body))
  17. respRecorder := httptest.NewRecorder()
  18. handler.WsHandler(respRecorder, req)
  19. resp := respRecorder.Result()
  20. if resp.StatusCode != http.StatusSwitchingProtocols {
  21. t.Errorf("expected status %v; got %v", http.StatusSwitchingProtocols, resp.StatusCode)
  22. }
  23. }

完整代码示例结构

  • main.go : 启动 HTTP 服务
  • api/websocket.api : 定义 API
  • handler/ws_handler.go : 实现 WebSocket 处理
  • tests/ws_handler_test.go : 测试用例

如何运行服务和测试用例

  1. 确保你已经安装了相关依赖项。
  2. 在项目根目录下运行以下命令以启动服务器:
  1. go run main.go handler/ws_handler.go
  1. 使用工具(如 Postman 或浏览器)连接到 /ws 路径进行测试。可以通过 JavaScript 创建一个简单的前端来与这个接口交互。
  2. 为了运行测试用例,在终端中执行以下命令:
  1. go test ./tests/...

这是一个完整且可运行的基础框架,你可以根据需要扩展更复杂的功能。如果有其他具体需求,请随时告诉我!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22732

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?