package im // //import ( // "encoding/json" // "flag" // "fmt" // "git.rosy.net.cn/baseapi/utils" // "io" // "log" // "net" // "net/http" // "sync" // "time" // // "git.rosy.net.cn/baseapi/platformapi/mtwmapi" // "git.rosy.net.cn/jx-callback/globals/api" // "github.com/gazeboxu/mapstructure" // "github.com/gorilla/websocket" // "gopkg.in/ini.v1" //) // //// ClientManager 连接管理 //type ClientManager struct { // ClientIdMap map[string]*Client // 全部的连接 // ClientIdMapLock sync.RWMutex // 读写锁 // // Connect chan *Client // 连接处理 // DisConnect chan *Client // 断开连接处理 // // GroupLock sync.RWMutex // Groups map[string][]string // // SystemClientsLock sync.RWMutex // SystemClients map[string][]string //} // //// Client 客户端连接信息 //type Client struct { // ClientId string // 标识ID // Socket *websocket.Conn // 用户连接 // ConnectTime uint64 // 首次连接时间 // IsDeleted bool // 是否删除或下线 // UserId string // 业务端标识用户ID // //Extend string // 扩展字段,用户可以自定义 // //GroupList []string //} // ////channel通道结构体 //type clientInfo struct { // ClientId string `json:"clientId" validate:"required"` //链接ID // Data interface{} // SendUserId string // MessageId string // Code int // Msg string //} // //// RetData 统一返回值结构体 //type RetData struct { // Code int `json:"code"` //响应code // Msg string `json:"msg"` //响应msg success/fail // Data interface{} `json:"data"` //信息 // // //MessageType string `json:"messageType"` //消息类型 heart-心跳检测;send-发送消息;receive-接收消息 // //MessageId string `json:"messageId"` //发送/接收信息 id // //UserId string `json:"userId"` //必须是平台方userID //} // //type global struct { // LocalHost string //本机内网IP // ServerList map[string]string // ServerListLock sync.RWMutex //} //type commonConf struct { // HttpPort string // RPCPort string // Cluster bool // CryptoKey string //} // //// SendData 客户端写入参数 //type SendData struct { // //ClientId string `json:"clientId" validate:"required"` //链接ID // VendorID int `json:"vendorID"` //消息来源平台ID // Data interface{} `json:"data"` //发送给平台 美团/饿了么消息结构体 // //返回值 // //Code int `json:"code"` // //Msg string `json:"msg"` // //SendUserId string `json:"sendUserId"` //} // //// JXMsg 京西消息结构体 //type JXMsg struct { // SendType string `json:"sendType"` //消息发送方 jx-商家;mt-美团;elm-饿了么 // Data interface{} `json:"data"` //美团/饿了么 单聊消息 //} // //// GetUserListReq 获取门店用户聊天列表 //type GetUserListReq struct { // VendorStoreID string `json:"vendorStoreID"` //平台门店id // VendorID string `json:"vendorID"` //平台标识id // AppID string `json:"appID"` //应用ID //} // //type GetChatDetailReq struct { // VendorStoreID string `json:"vendorStoreID"` //平台门店id // VendorID string `json:"vendorID"` //平台标识id // AppID string `json:"appID"` //应用ID // UserID string `json:"userID"` //userID/groupID //} // //// UserMessageList 用户消息列表 //type UserMessageList struct { // VendorID int `json:"vendorID"` //平台品牌 10-美团 11-饿了么 // UserID string `json:"userID"` //用户ID // NewMessageNum int `json:"NewMessageNum"` //新消息数量 // LatestMsg string `json:"latestMsg"` //最新一条消息 // LatestTime int `json:"latestTime"` //最新一条消息发送时间 //} // //type RelInfo struct { // VendorStoreID string `json:"vendorStoreID"` //平台门店id // VendorID string `json:"vendorID"` //平台标识id // AppID string `json:"appID"` //应用ID //} // //type UserRelInfo struct { // VendorStoreID string `json:"vendorStoreID"` //平台门店id // VendorID string `json:"vendorID"` //平台标识id // AppID string `json:"appID"` //应用ID // UserID string `json:"userID"` //用户id/groupID //} // //var ( // cfg *ini.File // rdb = api.Cacher // Manager = NewClientManager() // 管理者 // CommonSetting = &commonConf{} // GlobalSetting = &global{} // ToClientChan chan clientInfo // heartbeatInterval = 60 * time.Second // 心跳间隔 // HeartCheckMsg = "~#HHHBBB#~" //心跳检测消息 // HeartCheckSuccess = "HB" //成功发送返回心跳消息 // VendorIDMT = 10 //im美团 // VendorIDELM = 11 //im饿了么 // SendTypeJx = "jx" //京西客户端发送方标识 // SendTypeMt = "mt" //美团用户发送方标识符 // SendTypeElm = "elm" //饿了么用户发送方标识符 // MTIMPushUrl = "wss://wpush.meituan.com/websocket" //buildPushConnect建立长连接 //) // //const ( // ExpireTimeDay = 24 * time.Hour //redis一天过期时间 // maxMessageSize = 8192 // 最大的消息大小 //) // //type renderData struct { // ClientId string `json:"clientId"` //} // //const ( // SuccessCode = 0 // SuccessMsg = "success" // Fail = -1 // FailMsg = "fail" // // SYSTEM_ID_ERROR = -1001 // ONLINE_MESSAGE_CODE = 1001 // OFFLINE_MESSAGE_CODE = 1002 //) // //// Render 统一返回值 //func Render(conn *websocket.Conn, messageId string, code int, message string, data interface{}) error { // return conn.WriteJSON(RetData{ // Code: code, // Msg: message, // Data: data, // }) //} // //func ClientRender(w http.ResponseWriter, code int, msg string, data interface{}) (str string) { // var retData RetData // // retData.Code = code // retData.Msg = msg // retData.Data = data // // retJson, _ := json.Marshal(retData) // str = string(retJson) // // w.Header().Set("Content-Type", "application/json; charset=utf-8") // _, _ = io.WriteString(w, str) // return //} // //func ConnRender(conn *websocket.Conn, data interface{}) (err error) { // err = conn.WriteJSON(RetData{ // Code: SuccessCode, // Msg: "success", // Data: data, // }) // return //} // //// Default 给默认值 //func Default() { // CommonSetting = &commonConf{ // HttpPort: "6000", // RPCPort: "7000", // Cluster: false, // CryptoKey: "Adba723b7fe06819", // } // // GlobalSetting = &global{ // LocalHost: getIntranetIp(), // ServerList: make(map[string]string), // } //} // //// Setup 初始化全局设置变量 //func Setup() { // configFile := flag.String("c", "conf/app.ini", "-c conf/app.ini") // // var err error // cfg, err = ini.Load(*configFile) // if err != nil { // log.Fatalf("setting.Setup, fail to parse 'conf/app.ini': %v", err) // } // // mapTo("common", CommonSetting) // // GlobalSetting = &global{ // LocalHost: getIntranetIp(), // ServerList: make(map[string]string), // } // fmt.Printf("LocalHost=%s\n ServerList=%s\n", GlobalSetting.LocalHost, utils.Format4Output(GlobalSetting.ServerList, false)) //} // //// mapTo map section //func mapTo(section string, v interface{}) { // err := cfg.Section(section).MapTo(v) // if err != nil { // log.Fatalf("Cfg.MapTo %s err: %v", section, err) // } //} // ////获取本机IP //func getIntranetIp() string { // addrs, _ := net.InterfaceAddrs() // for _, addr := range addrs { // // 检查ip地址判断是否回环地址 // if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { // if ipnet.IP.To4() != nil { // return ipnet.IP.String() // } // // } // } // return "" //} // //// GenFullUrl 组装完整websocket url以及生成clientID //func GenFullUrl() (fullUrl string) { // resp, err := api.MtwmAPI.GetConnectionToken() // if err != nil { // return "" // } // retVal := mtwmapi.GetConnTokenResp{} // err = mapstructure.Decode(resp, &retVal) // fullUrl = MTIMPushUrl + "/" + retVal.AppKey + "/" + retVal.ConnectionToken // //clientID = api.MtwmAPI.GetAppID() + ":" + retVal.ConnectionToken // //打印输出 // //fmt.Printf("Create websocket connect failCount:%d", retVal.UserCount) // return fullUrl //}