client.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. c.write(&Message{Id: id, Data: data})
  40. }
  41. func (c *Client) Event(data interface{}, ev string, id int) {
  42. c.write(&Message{Id: id, Data: data, Event: ev})
  43. }
  44. func (c *Client) write(msg *Message) {
  45. select {
  46. case c.ch <- msg:
  47. default:
  48. c.server.Del(c)
  49. err := fmt.Errorf("client %d is disconnected.", c.id)
  50. c.server.Err(err)
  51. }
  52. }
  53. func (c *Client) Done() {
  54. c.doneCh <- true
  55. }
  56. // Listen Write and Read request via chanel
  57. func (c *Client) Listen() {
  58. go c.listenWrite()
  59. c.listenRead()
  60. }
  61. // Listen write request via chanel
  62. func (c *Client) listenWrite() {
  63. for {
  64. select {
  65. // send message to the client
  66. case msg := <-c.ch:
  67. wslogger.Debugln("Send:", msg)
  68. ws.JSON.Send(c.ws, msg)
  69. // receive done request
  70. case <-c.doneCh:
  71. c.server.Del(c)
  72. c.doneCh <- true // for listenRead method
  73. return
  74. }
  75. }
  76. }
  77. // Listen read request via chanel
  78. func (c *Client) listenRead() {
  79. for {
  80. select {
  81. // receive done request
  82. case <-c.doneCh:
  83. c.server.Del(c)
  84. c.doneCh <- true // for listenWrite method
  85. return
  86. // read data from ws connection
  87. default:
  88. var msg Message
  89. err := ws.JSON.Receive(c.ws, &msg)
  90. if err == io.EOF {
  91. c.doneCh <- true
  92. } else if err != nil {
  93. c.server.Err(err)
  94. } else {
  95. wslogger.Debugln(&msg)
  96. if c.onMessage != nil {
  97. c.onMessage(c, &msg)
  98. }
  99. }
  100. }
  101. }
  102. }