websocket.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package ecal
  11. import (
  12. "encoding/json"
  13. "sync"
  14. "time"
  15. "github.com/gorilla/websocket"
  16. )
  17. /*
  18. WebsocketConnection models a single websocket connection.
  19. Websocket connections support one concurrent reader and one concurrent writer.
  20. See: https://godoc.org/github.com/gorilla/websocket#hdr-Concurrency
  21. */
  22. type WebsocketConnection struct {
  23. CommID string
  24. Conn *websocket.Conn
  25. RMutex *sync.Mutex
  26. WMutex *sync.Mutex
  27. }
  28. /*
  29. NewWebsocketConnection creates a new WebsocketConnection object.
  30. */
  31. func NewWebsocketConnection(commID string, c *websocket.Conn) *WebsocketConnection {
  32. return &WebsocketConnection{
  33. CommID: commID,
  34. Conn: c,
  35. RMutex: &sync.Mutex{},
  36. WMutex: &sync.Mutex{}}
  37. }
  38. /*
  39. Init initializes the websocket connection.
  40. */
  41. func (wc *WebsocketConnection) Init() {
  42. wc.WMutex.Lock()
  43. defer wc.WMutex.Unlock()
  44. wc.Conn.WriteMessage(websocket.TextMessage, []byte(`{"type":"init_success","payload":{}}`))
  45. }
  46. /*
  47. ReadData reads data from the websocket connection.
  48. */
  49. func (wc *WebsocketConnection) ReadData() (map[string]interface{}, bool, error) {
  50. var data map[string]interface{}
  51. var fatal = true
  52. wc.RMutex.Lock()
  53. _, msg, err := wc.Conn.ReadMessage()
  54. wc.RMutex.Unlock()
  55. if err == nil {
  56. fatal = false
  57. err = json.Unmarshal(msg, &data)
  58. }
  59. return data, fatal, err
  60. }
  61. /*
  62. WriteData writes data to the websocket.
  63. */
  64. func (wc *WebsocketConnection) WriteData(data map[string]interface{}) {
  65. wc.WMutex.Lock()
  66. defer wc.WMutex.Unlock()
  67. jsonData, _ := json.Marshal(map[string]interface{}{
  68. "commID": wc.CommID,
  69. "type": "data",
  70. "payload": data,
  71. })
  72. wc.Conn.WriteMessage(websocket.TextMessage, jsonData)
  73. }
  74. /*
  75. Close closes the websocket connection.
  76. */
  77. func (wc *WebsocketConnection) Close(msg string) {
  78. wc.Conn.WriteControl(websocket.CloseMessage,
  79. websocket.FormatCloseMessage(
  80. websocket.CloseNormalClosure, msg), time.Now().Add(10*time.Second))
  81. wc.Conn.Close()
  82. }