forked from openimsdk/openim-sdk-core
/
ws_handle.go
213 lines (188 loc) · 5.56 KB
/
ws_handle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package ws_local_server
import (
"encoding/json"
"errors"
"reflect"
"runtime"
"strconv"
"strings"
"time"
"github.com/erbaner/be-core/pkg/log"
"github.com/erbaner/be-core/sdk_struct"
"github.com/erbaner/be-core/ws_wrapper/utils"
"github.com/gorilla/websocket"
)
type EventData struct {
Event string `json:"event"`
ErrCode int32 `json:"errCode"`
ErrMsg string `json:"errMsg"`
Data string `json:"data"`
OperationID string `json:"operationID"`
}
type BaseSuccessFailed struct {
funcName string //e.g open_im_sdk/open_im_sdk.Login
operationID string
uid string
}
// e.g open_im_sdk/open_im_sdk.Login ->Login
func cleanUpfuncName(funcName string) string {
end := strings.LastIndex(funcName, ".")
if end == -1 {
log.Info("", "funcName not include.", funcName)
return ""
}
return funcName[end+1:]
}
func (b *BaseSuccessFailed) OnError(errCode int32, errMsg string) {
log.Info("", "!!!!!!!OnError ", b.uid, b.operationID, b.funcName)
SendOneUserMessage(EventData{cleanUpfuncName(b.funcName), errCode, errMsg, "", b.operationID}, b.uid)
}
func (b *BaseSuccessFailed) OnSuccess(data string) {
log.Info("", "!!!!!!!OnSuccess ", b.uid, b.operationID, b.funcName)
SendOneUserMessage(EventData{cleanUpfuncName(b.funcName), 0, "", data, b.operationID}, b.uid)
}
func runFuncName() string {
pc := make([]uintptr, 1)
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
return f.Name()
}
func int32ToString(i int32) string {
return strconv.FormatInt(int64(i), 10)
}
func int64ToString(i int64) string {
return strconv.FormatInt(i, 10)
}
//uid->funcname->func
type WsFuncRouter struct {
uId string
//conn *UserConn
}
func DelUserRouter(uid string, operationID string) {
log.Info(operationID, "DelUserRouter ", uid)
sub := " " + utils.PlatformIDToName(sdk_struct.SvrConf.Platform)
idx := strings.LastIndex(uid, sub)
if idx == -1 {
log.Info(operationID, "err uid, not Web", uid, sub)
return
}
uid = uid[:idx]
UserRouteRwLock.Lock()
defer UserRouteRwLock.Unlock()
urm, ok := UserRouteMap[uid]
if ok {
log.Info(operationID, "DelUserRouter logout, UnInitSDK ", uid, operationID)
urm.wsRouter.LogoutNoCallback(uid, operationID)
urm.wsRouter.UnInitSDK()
} else {
log.Info(operationID, "no found UserRouteMap: ", uid)
}
log.Info(operationID, "DelUserRouter delete ", uid)
t, ok := UserRouteMap[uid]
if ok {
t.refName = make(map[string]reflect.Value)
}
delete(UserRouteMap, uid)
}
func GenUserRouterNoLock(uid string, batchMsg int, operationID string) *RefRouter {
_, ok := UserRouteMap[uid]
if ok {
return nil
}
RouteMap1 := make(map[string]reflect.Value, 0)
var wsRouter1 WsFuncRouter
wsRouter1.uId = uid
vf := reflect.ValueOf(&wsRouter1)
vft := vf.Type()
mNum := vf.NumMethod()
for i := 0; i < mNum; i++ {
mName := vft.Method(i).Name
log.Info(operationID, "index:", i, " MethodName:", mName)
RouteMap1[mName] = vf.Method(i)
}
wsRouter1.InitSDK(ConfigSvr, operationID)
log.Info(operationID, "SetAdvancedMsgListener() ", uid)
wsRouter1.SetAdvancedMsgListener()
if batchMsg == 1 {
log.Info(operationID, "SetBatchMsgListener() ", uid)
wsRouter1.SetBatchMsgListener()
}
wsRouter1.SetConversationListener()
log.Info(operationID, "SetFriendListener() ", uid)
wsRouter1.SetFriendListener()
log.Info(operationID, "SetGroupListener() ", uid)
wsRouter1.SetGroupListener()
log.Info(operationID, "SetUserListener() ", uid)
wsRouter1.SetUserListener()
log.Info(operationID, "SetSignalingListener() ", uid)
wsRouter1.SetSignalingListener()
log.Info(operationID, "setWorkMomentsListener()", uid)
wsRouter1.SetWorkMomentsListener()
log.Info(operationID, "SetOrganizationListener()", uid)
wsRouter1.SetOrganizationListener()
var rr RefRouter
rr.refName = RouteMap1
rr.wsRouter = &wsRouter1
UserRouteMap[uid] = rr
log.Info(operationID, "insert UserRouteMap: ", uid)
return &rr
}
func (wsRouter *WsFuncRouter) GlobalSendMessage(data interface{}) {
SendOneUserMessage(data, wsRouter.uId)
}
// listener
func SendOneUserMessage(data interface{}, uid string) {
var chMsg ChanMsg
chMsg.data, _ = json.Marshal(data)
chMsg.uid = uid
err := send2Ch(WS.ch, &chMsg, 2)
if err != nil {
log.Info("", "send2ch failed, ", err, string(chMsg.data), uid)
return
}
log.Info("", "send response to web: ", string(chMsg.data))
}
func SendOneUserMessageForTest(data interface{}, uid string) {
d, err := json.Marshal(data)
log.Info("", "Marshal ", string(d))
var chMsg ChanMsg
chMsg.data = d
chMsg.uid = uid
err = send2ChForTest(WS.ch, chMsg, 2)
if err != nil {
log.Info("", "send2ch failed, ", err, string(chMsg.data), uid)
return
}
log.Info("", "send response to web: ", string(chMsg.data))
}
func SendOneConnMessage(data interface{}, conn *UserConn) {
bMsg, _ := json.Marshal(data)
err := WS.writeMsg(conn, websocket.TextMessage, bMsg)
log.Info("", "send response to web: ", string(bMsg), "userUid", WS.getUserUid(conn))
if err != nil {
log.Info("", "WS WriteMsg error", "", "userIP", conn.RemoteAddr().String(), "userUid", WS.getUserUid(conn), "error", err, "data", data)
} else {
log.Info("", "WS WriteMsg ok", "data", data, "userUid", WS.getUserUid(conn))
}
}
func send2ChForTest(ch chan ChanMsg, value ChanMsg, timeout int64) error {
var t ChanMsg
t = value
log.Info("", "test uid ", t.uid)
return nil
}
func send2Ch(ch chan ChanMsg, value *ChanMsg, timeout int64) error {
var flag = 0
select {
case ch <- *value:
flag = 1
case <-time.After(time.Second * time.Duration(timeout)):
flag = 2
}
if flag == 1 {
return nil
} else {
log.Info("", "send cmd timeout, ", timeout, value)
return errors.New("send cmd timeout")
}
}