client.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // 客户端管理模块
  2. // 处理单个 WebSocket 客户端的连接、消息读取和发送
  3. package wsClient
  4. import (
  5. "encoding/json"
  6. "fmt"
  7. "github.com/gorilla/websocket" // WebSocket 库
  8. )
  9. // Client represents connection to a single chatting user
  10. // Client 表示一个聊天用户的连接
  11. // 每个 WebSocket 连接对应一个 Client 实例
  12. type Client struct {
  13. // a socket is the web socket for this uer
  14. // WebSocket 连接对象,用于与浏览器端进行双向通信
  15. socket *websocket.Conn
  16. //receive is a channel to receive messages from other clients
  17. // 用于接收来自其他客户端的消息的 channel
  18. // 房间会将广播的消息发送到这个 channel
  19. receive chan []byte
  20. //room is where the client is chatting in
  21. // 客户端所在的聊天房间引用
  22. // 用于将发送的消息转发给房间
  23. room *Room
  24. // 客户端的显示名称(用户名)
  25. // 在消息中用于标识消息发送者
  26. name string
  27. }
  28. // read 从 WebSocket 连接读取消息并转发给房间 (原作者说: Used to send messages)
  29. // 这个方法会阻塞运行直到连接断开或出现错误
  30. func (c *Client) read() {
  31. // close the connection when we are done
  32. defer c.socket.Close()
  33. // endlessly read messages from input
  34. for {
  35. // 从 WebSocket 连接读取消息
  36. // _ 表示忽略消息类型,msg 是消息内容,err 是错误
  37. _, msg, err := c.socket.ReadMessage()
  38. // break if there is an error
  39. if err != nil {
  40. return
  41. }
  42. // 构造要发送的消息对象,包含用户名和消息内容
  43. outgoing := map[string]string{
  44. "name": c.name, // 发送者用户名
  45. "message": string(msg), // 消息内容(转换为字符串)
  46. }
  47. // 将消息对象编码为 JSON 格式
  48. jsMessage, err := json.Marshal(outgoing)
  49. if err != nil {
  50. fmt.Println("Enconding failed!")
  51. continue
  52. }
  53. // 将编码后的消息和发送者信息一起发送到房间的 forward channel
  54. c.room.forward <- &message{
  55. content: jsMessage, // 消息内容
  56. sender: c, // 发送者(当前客户端)
  57. }// 房间会将这条消息分发给除发送者外的所有其他客户端(在 room.go 中 run() 方法 case msg := <-r.forward 中)
  58. }
  59. }
  60. // write 从 receive channel 读取消息并发送给客户端
  61. // 在独立的 goroutine 中运行,处理向客户端发送消息的任务
  62. func (c *Client) write() {
  63. defer c.socket.Close()
  64. // 循环从 receive channel 读取消息
  65. for msg := range c.receive {
  66. err := c.socket.WriteMessage(websocket.TextMessage, msg)
  67. if err != nil {
  68. return
  69. }
  70. }
  71. }