diff options
author | Joram Wilander <jwawilander@gmail.com> | 2017-03-28 04:58:19 -0400 |
---|---|---|
committer | George Goldberg <george@gberg.me> | 2017-03-28 09:58:19 +0100 |
commit | daca0d93f621bcb1daae149c178af0631bcd120a (patch) | |
tree | 6127936c76dbc6fd20a7377385469980e5bd72e3 /wsapi | |
parent | ca8b8d1245026672b1a56d256bb8ff3c8bb1bba9 (diff) | |
download | chat-daca0d93f621bcb1daae149c178af0631bcd120a.tar.gz chat-daca0d93f621bcb1daae149c178af0631bcd120a.tar.bz2 chat-daca0d93f621bcb1daae149c178af0631bcd120a.zip |
Move WebSocket API to it's own package and add websocket v4 endpoint (#5881)
Diffstat (limited to 'wsapi')
-rw-r--r-- | wsapi/api.go | 21 | ||||
-rw-r--r-- | wsapi/status.go | 38 | ||||
-rw-r--r-- | wsapi/system.go | 27 | ||||
-rw-r--r-- | wsapi/user.go | 40 | ||||
-rw-r--r-- | wsapi/webrtc.go | 31 | ||||
-rw-r--r-- | wsapi/websocket_handler.go | 61 |
6 files changed, 218 insertions, 0 deletions
diff --git a/wsapi/api.go b/wsapi/api.go new file mode 100644 index 000000000..2d4c99674 --- /dev/null +++ b/wsapi/api.go @@ -0,0 +1,21 @@ +// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + "github.com/mattermost/platform/app" +) + +func InitRouter() { + app.Srv.WebSocketRouter = app.NewWebSocketRouter() +} + +func InitApi() { + InitUser() + InitSystem() + InitStatus() + InitWebrtc() + + app.HubStart() +} diff --git a/wsapi/status.go b/wsapi/status.go new file mode 100644 index 000000000..a9ff8831d --- /dev/null +++ b/wsapi/status.go @@ -0,0 +1,38 @@ +// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + l4g "github.com/alecthomas/log4go" + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func InitStatus() { + l4g.Debug(utils.T("wsapi.status.init.debug")) + + app.Srv.WebSocketRouter.Handle("get_statuses", ApiWebSocketHandler(getStatuses)) + app.Srv.WebSocketRouter.Handle("get_statuses_by_ids", ApiWebSocketHandler(getStatusesByIds)) +} + +func getStatuses(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) { + statusMap := app.GetAllStatuses() + return model.StatusMapToInterfaceMap(statusMap), nil +} + +func getStatusesByIds(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) { + var userIds []string + if userIds = model.ArrayFromInterface(req.Data["user_ids"]); len(userIds) == 0 { + l4g.Error(model.StringInterfaceToJson(req.Data)) + return nil, NewInvalidWebSocketParamError(req.Action, "user_ids") + } + + statusMap, err := app.GetStatusesByIds(userIds) + if err != nil { + return nil, err + } + + return statusMap, nil +} diff --git a/wsapi/system.go b/wsapi/system.go new file mode 100644 index 000000000..644d0196f --- /dev/null +++ b/wsapi/system.go @@ -0,0 +1,27 @@ +// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + l4g "github.com/alecthomas/log4go" + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func InitSystem() { + l4g.Debug(utils.T("wsapi.system.init.debug")) + + app.Srv.WebSocketRouter.Handle("ping", ApiWebSocketHandler(ping)) +} + +func ping(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) { + data := map[string]interface{}{} + data["text"] = "pong" + data["version"] = model.CurrentVersion + data["server_time"] = model.GetMillis() + data["node_id"] = "" + + return data, nil +} diff --git a/wsapi/user.go b/wsapi/user.go new file mode 100644 index 000000000..a89bf1118 --- /dev/null +++ b/wsapi/user.go @@ -0,0 +1,40 @@ +// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + l4g "github.com/alecthomas/log4go" + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func InitUser() { + l4g.Debug(utils.T("wsapi.user.init.debug")) + + app.Srv.WebSocketRouter.Handle("user_typing", ApiWebSocketHandler(userTyping)) +} + +func userTyping(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) { + var ok bool + var channelId string + if channelId, ok = req.Data["channel_id"].(string); !ok || len(channelId) != 26 { + return nil, NewInvalidWebSocketParamError(req.Action, "channel_id") + } + + var parentId string + if parentId, ok = req.Data["parent_id"].(string); !ok { + parentId = "" + } + + omitUsers := make(map[string]bool, 1) + omitUsers[req.Session.UserId] = true + + event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_TYPING, "", channelId, "", omitUsers) + event.Add("parent_id", parentId) + event.Add("user_id", req.Session.UserId) + go app.Publish(event) + + return nil, nil +} diff --git a/wsapi/webrtc.go b/wsapi/webrtc.go new file mode 100644 index 000000000..fd8eede30 --- /dev/null +++ b/wsapi/webrtc.go @@ -0,0 +1,31 @@ +// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + l4g "github.com/alecthomas/log4go" + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func InitWebrtc() { + l4g.Debug(utils.T("wsapi.webtrc.init.debug")) + + app.Srv.WebSocketRouter.Handle("webrtc", ApiWebSocketHandler(webrtcMessage)) +} + +func webrtcMessage(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) { + var ok bool + var toUserId string + if toUserId, ok = req.Data["to_user_id"].(string); !ok || len(toUserId) != 26 { + return nil, NewInvalidWebSocketParamError(req.Action, "to_user_id") + } + + event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_WEBRTC, "", "", toUserId, nil) + event.Data = req.Data + go app.Publish(event) + + return nil, nil +} diff --git a/wsapi/websocket_handler.go b/wsapi/websocket_handler.go new file mode 100644 index 000000000..193539242 --- /dev/null +++ b/wsapi/websocket_handler.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package wsapi + +import ( + l4g "github.com/alecthomas/log4go" + + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func ApiWebSocketHandler(wh func(*model.WebSocketRequest) (map[string]interface{}, *model.AppError)) webSocketHandler { + return webSocketHandler{wh} +} + +type webSocketHandler struct { + handlerFunc func(*model.WebSocketRequest) (map[string]interface{}, *model.AppError) +} + +func (wh webSocketHandler) ServeWebSocket(conn *app.WebConn, r *model.WebSocketRequest) { + l4g.Debug("/api/v3/users/websocket:%s", r.Action) + + session, sessionErr := app.GetSession(conn.SessionToken) + if sessionErr != nil { + l4g.Error(utils.T("api.web_socket_handler.log.error"), "/api/v3/users/websocket", r.Action, r.Seq, conn.UserId, sessionErr.SystemMessage(utils.T), sessionErr.Error()) + sessionErr.DetailedError = "" + errResp := model.NewWebSocketError(r.Seq, sessionErr) + errResp.DoPreComputeJson() + + conn.Send <- errResp + return + } + + r.Session = *session + r.T = conn.T + r.Locale = conn.Locale + + var data map[string]interface{} + var err *model.AppError + + if data, err = wh.handlerFunc(r); err != nil { + l4g.Error(utils.T("api.web_socket_handler.log.error"), "/api/v3/users/websocket", r.Action, r.Seq, r.Session.UserId, err.SystemMessage(utils.T), err.DetailedError) + err.DetailedError = "" + errResp := model.NewWebSocketError(r.Seq, err) + errResp.DoPreComputeJson() + + conn.Send <- errResp + return + } + + resp := model.NewWebSocketResponse(model.STATUS_OK, r.Seq, data) + resp.DoPreComputeJson() + + conn.Send <- resp +} + +func NewInvalidWebSocketParamError(action string, name string) *model.AppError { + return model.NewLocAppError("/api/v3/users/websocket:"+action, "api.websocket_handler.invalid_param.app_error", map[string]interface{}{"Name": name}, "") +} |