summaryrefslogtreecommitdiffstats
path: root/model/websocket_client.go
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2016-07-12 09:36:27 -0400
committerGitHub <noreply@github.com>2016-07-12 09:36:27 -0400
commitad343a0f4ad175053f7d0da12a0587bcbb396d1c (patch)
tree8e1be00202a1d3a037ec75879538eb0ba1f25c01 /model/websocket_client.go
parent06eacf30b97aacf6544552448635b7f078d2c90b (diff)
downloadchat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.tar.gz
chat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.tar.bz2
chat-ad343a0f4ad175053f7d0da12a0587bcbb396d1c.zip
Added infrastructure for basic WebSocket API (#3432)
Diffstat (limited to 'model/websocket_client.go')
-rw-r--r--model/websocket_client.go102
1 files changed, 102 insertions, 0 deletions
diff --git a/model/websocket_client.go b/model/websocket_client.go
new file mode 100644
index 000000000..7b9dc0b50
--- /dev/null
+++ b/model/websocket_client.go
@@ -0,0 +1,102 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "github.com/gorilla/websocket"
+ "net/http"
+)
+
+type WebSocketClient struct {
+ Url string // The location of the server like "ws://localhost:8065"
+ ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"
+ Conn *websocket.Conn // The WebSocket connection
+ AuthToken string // The token used to open the WebSocket
+ Sequence int64 // The ever-incrementing sequence attached to each WebSocket action
+ EventChannel chan *WebSocketEvent
+ ResponseChannel chan *WebSocketResponse
+}
+
+// NewWebSocketClient constructs a new WebSocket client with convienence
+// methods for talking to the server.
+func NewWebSocketClient(url, authToken string) (*WebSocketClient, *AppError) {
+ header := http.Header{}
+ header.Set(HEADER_AUTH, "BEARER "+authToken)
+ conn, _, err := websocket.DefaultDialer.Dial(url+API_URL_SUFFIX+"/users/websocket", header)
+ if err != nil {
+ return nil, NewLocAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error())
+ }
+
+ return &WebSocketClient{
+ url,
+ url + API_URL_SUFFIX,
+ conn,
+ authToken,
+ 1,
+ make(chan *WebSocketEvent, 100),
+ make(chan *WebSocketResponse, 100),
+ }, nil
+}
+
+func (wsc *WebSocketClient) Connect() *AppError {
+ header := http.Header{}
+ header.Set(HEADER_AUTH, "BEARER "+wsc.AuthToken)
+
+ var err error
+ wsc.Conn, _, err = websocket.DefaultDialer.Dial(wsc.ApiUrl+"/users/websocket", header)
+ if err != nil {
+ return NewLocAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error())
+ }
+
+ return nil
+}
+
+func (wsc *WebSocketClient) Close() {
+ wsc.Conn.Close()
+}
+
+func (wsc *WebSocketClient) Listen() {
+ go func() {
+ for {
+ var rawMsg json.RawMessage
+ var err error
+ if _, rawMsg, err = wsc.Conn.ReadMessage(); err != nil {
+ return
+ }
+
+ var event WebSocketEvent
+ if err := json.Unmarshal(rawMsg, &event); err == nil && event.IsValid() {
+ wsc.EventChannel <- &event
+ continue
+ }
+
+ var response WebSocketResponse
+ if err := json.Unmarshal(rawMsg, &response); err == nil && response.IsValid() {
+ wsc.ResponseChannel <- &response
+ continue
+ }
+ }
+ }()
+}
+
+func (wsc *WebSocketClient) SendMessage(action string, data map[string]interface{}) {
+ req := &WebSocketRequest{}
+ req.Seq = wsc.Sequence
+ req.Action = action
+ req.Data = data
+
+ wsc.Sequence++
+
+ wsc.Conn.WriteJSON(req)
+}
+
+func (wsc *WebSocketClient) UserTyping(channelId, parentId string) {
+ data := map[string]interface{}{
+ "channel_id": channelId,
+ "parent_id": parentId,
+ }
+
+ wsc.SendMessage("user_typing", data)
+}