client.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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{}, seed int) {
  39. msg := &Message{Seed: seed, 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. logger.Debugln("Listening write to client")
  59. for {
  60. select {
  61. // send message to the client
  62. case msg := <-c.ch:
  63. logger.Debugln("Send:", msg)
  64. ws.JSON.Send(c.ws, msg)
  65. // receive done request
  66. case <-c.doneCh:
  67. c.server.Del(c)
  68. c.doneCh <- true // for listenRead method
  69. return
  70. }
  71. }
  72. }
  73. // Listen read request via chanel
  74. func (c *Client) listenRead() {
  75. logger.Debugln("Listening read from client")
  76. for {
  77. select {
  78. // receive done request
  79. case <-c.doneCh:
  80. c.server.Del(c)
  81. c.doneCh <- true // for listenWrite method
  82. return
  83. // read data from ws connection
  84. default:
  85. var msg Message
  86. err := ws.JSON.Receive(c.ws, &msg)
  87. if err == io.EOF {
  88. c.doneCh <- true
  89. } else if err != nil {
  90. c.server.Err(err)
  91. } else {
  92. logger.Debugln(&msg)
  93. if c.onMessage != nil {
  94. c.onMessage(c, &msg)
  95. }
  96. }
  97. }
  98. }
  99. }