client.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package websocket
  2. import (
  3. "fmt"
  4. "io"
  5. ws "code.google.com/p/go.net/websocket"
  6. )
  7. const channelBufSize = 100
  8. var maxId int = 0
  9. type MsgFunc func(c *Client, msg *Message)
  10. // Chat client.
  11. type Client struct {
  12. id int
  13. ws *ws.Conn
  14. server *Server
  15. ch chan *Message
  16. doneCh chan bool
  17. onMessage MsgFunc
  18. }
  19. // Create new chat client.
  20. func NewClient(ws *ws.Conn, server *Server) *Client {
  21. if ws == nil {
  22. panic("ws cannot be nil")
  23. }
  24. if server == nil {
  25. panic("server cannot be nil")
  26. }
  27. maxId++
  28. ch := make(chan *Message, channelBufSize)
  29. doneCh := make(chan bool)
  30. return &Client{maxId, ws, server, ch, doneCh, nil}
  31. }
  32. func (c *Client) Id() int {
  33. return c.id
  34. }
  35. func (c *Client) Conn() *ws.Conn {
  36. return c.ws
  37. }
  38. func (c *Client) Write(data interface{}, id int) {
  39. msg := &Message{Id: id, Data: data}
  40. select {
  41. case c.ch <- msg:
  42. default:
  43. c.server.Del(c)
  44. err := fmt.Errorf("client %d is disconnected.", c.id)
  45. c.server.Err(err)
  46. }
  47. }
  48. func (c *Client) Done() {
  49. c.doneCh <- true
  50. }
  51. // Listen Write and Read request via chanel
  52. func (c *Client) Listen() {
  53. go c.listenWrite()
  54. c.listenRead()
  55. }
  56. // Listen write request via chanel
  57. func (c *Client) listenWrite() {
  58. for {
  59. select {
  60. // send message to the client
  61. case msg := <-c.ch:
  62. wslogger.Debugln("Send:", msg)
  63. ws.JSON.Send(c.ws, msg)
  64. // receive done request
  65. case <-c.doneCh:
  66. c.server.Del(c)
  67. c.doneCh <- true // for listenRead method
  68. return
  69. }
  70. }
  71. }
  72. // Listen read request via chanel
  73. func (c *Client) listenRead() {
  74. for {
  75. select {
  76. // receive done request
  77. case <-c.doneCh:
  78. c.server.Del(c)
  79. c.doneCh <- true // for listenWrite method
  80. return
  81. // read data from ws connection
  82. default:
  83. var msg Message
  84. err := ws.JSON.Receive(c.ws, &msg)
  85. if err == io.EOF {
  86. c.doneCh <- true
  87. } else if err != nil {
  88. c.server.Err(err)
  89. } else {
  90. wslogger.Debugln(&msg)
  91. if c.onMessage != nil {
  92. c.onMessage(c, &msg)
  93. }
  94. }
  95. }
  96. }
  97. }