Browse Source

websocket.bak

wangshan 7 years ago
parent
commit
e46960ecb6
1 changed files with 261 additions and 0 deletions
  1. 261 0
      src/jfw/front/websocket.go.bak

+ 261 - 0
src/jfw/front/websocket.go.bak

@@ -0,0 +1,261 @@
+package front
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	qutil "qfw/util"
+	"qfw/util/redis"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-xweb/httpsession"
+	"github.com/go-xweb/xweb"
+	"github.com/gorilla/websocket"
+)
+
+var upgrader = websocket.Upgrader{
+	ReadBufferSize:  1024,
+	WriteBufferSize: 1024,
+}
+
+//socket对象放在内存中,待rpc回调使用
+type Wss struct {
+	Conn *websocket.Conn
+	Time int64
+}
+type MapSocket struct {
+	Map  map[string]*Wss
+	Lock sync.Mutex
+}
+
+func (m *MapSocket) GC() {
+	defer qutil.Catch()
+	m.Lock.Lock()
+	now := time.Now().Unix()
+	for k, v := range m.Map {
+		if now-v.Time > 3600 || v.Conn == nil {
+			delete(m.Map, k)
+		}
+	}
+	m.Lock.Unlock()
+	time.AfterFunc(5*time.Minute, m.GC)
+}
+
+var MSPOOL = 20
+var MapSocketArr = make([]*MapSocket, MSPOOL)
+
+//初始化
+func init() {
+	for i := 0; i < MSPOOL; i++ {
+		ms := &MapSocket{Map: map[string]*Wss{}}
+		go ms.GC()
+		MapSocketArr[i] = ms
+	}
+}
+
+//根据代码和ws做映射
+func PutWsByCode(src string, ws *websocket.Conn) {
+	defer qutil.Catch()
+	n := HashVal(src) % MSPOOL
+	ms := MapSocketArr[n]
+	ms.Lock.Lock()
+	ms.Map[src] = &Wss{ws, time.Now().Unix()}
+	ms.Lock.Unlock()
+}
+
+//计算代码的hash值
+func HashVal(src string) int {
+	check := 0
+	for i := len(src) / 2; i < len(src); i++ {
+		check += int(src[i])
+	}
+	return check
+}
+
+//rpc回调,写到前台
+func GetWsByCode(param []string) bool {
+	if len(param) < 2 {
+		return false
+	}
+	src := param[0]
+	openid := param[1]
+	if src == "" {
+		return false
+	}
+	defer qutil.Catch()
+	n := HashVal(src) % MSPOOL
+	ms := MapSocketArr[n]
+	defer func() {
+		ms.Lock.Lock()
+		delete(ms.Map, src)
+		ms.Lock.Unlock()
+	}()
+	ms.Lock.Lock()
+	wss := ms.Map[src]
+	ms.Lock.Unlock()
+	if wss != nil && wss.Conn != nil {
+		infoData := LoginInfo(src, openid, wss.Conn.Sess)
+		log.Println(infoData)
+		sendmessage, _ := json.Marshal(infoData)
+		if err := wss.Conn.WriteMessage(websocket.TextMessage, sendmessage); err != nil {
+			log.Println("socket send fail..", err)
+			return false
+		} else {
+			wss.Conn.Close()
+		}
+		return true
+	} else {
+		return false
+
+	}
+}
+
+//用户登录信息
+func LoginInfo(shareid, openid string, Sess interface{}) (infoData map[string]interface{}) {
+	if Sess == nil {
+		return nil
+	}
+	sess, _ := Sess.(*httpsession.Session)
+	infoData = make(map[string]interface{})
+	if openid != "" {
+		sess.Set("openid", openid)
+		redisheadimg := redis.Get("other", "newUser-"+openid)
+		if redisheadimg == nil {
+			redisheadimg = ""
+		}
+		user, _ := mongodb.FindOneByField("user", `{"s_m_openid":"`+openid+`"}`, `{"s_nickname":1,"s_headimage":1,"s_m_openid":1}`)
+		if user != nil && len(*user) > 0 {
+			infoData["result"] = "ok"
+			infoData["s_nickname"] = fmt.Sprint((*user)["s_nickname"])
+			infoData["s_headimage"] = fmt.Sprint((*user)["s_headimage"])
+			infoData["redisheadimg"] = fmt.Sprint(redisheadimg)
+			infoData["encryptId"] = se.EncodeString(qutil.BsonIdToSId((*user)["_id"]))
+			infoData["shareid"] = shareid
+			(*user)["shareid"] = shareid
+			nick := fmt.Sprint((*user)["s_nickname"])
+			sess.Set("nickname", nick)
+			sess.Set("s_nickname", nick)
+			sess.Set("s_m_openid", fmt.Sprint((*user)["s_m_openid"]))
+			sess.Set("user", *user)
+		}
+	}
+	return infoData
+}
+
+//登录关注
+func ServeWss(w http.ResponseWriter, r *http.Request) {
+	defer qutil.Catch()
+	conn, err := upgrader.Upgrade(w, r, nil)
+	conn.Sess = xweb.RootApp().SessionManager.Session(r, w)
+	var shareIds string
+	if err == nil {
+		for {
+			_, shareData, err := conn.ReadMessage()
+			log.Println("========wait", string(shareData))
+			if err != nil {
+				//log.Println("前台socket关闭,后台socket断开并退出循环。。。。")
+				break
+			} else {
+				//心跳监测
+				if string(shareData) == "HeartBeat" {
+					log.Println("send...", string(shareData))
+					conn.WriteMessage(websocket.TextMessage, []byte("\"HeartBeat\""))
+					continue
+				}
+				shareIds = string(shareData)
+				shareidlist := strings.Split(shareIds, "___")
+				if shareIds != "" && len(shareidlist) > 1 {
+					shareidnum := shareidlist[0]
+					shareidkop := shareidlist[1]
+					log.Println(se.DecodeString(shareidnum), se.DecodeString(shareidkop))
+					PutWsByCode(se.DecodeString(shareidnum), conn)
+					PutWsByCode(se.DecodeString(shareidkop), conn)
+					conn.WriteMessage(websocket.TextMessage, []byte("\"ok\""))
+				}
+			}
+		}
+	}
+}
+
+//实验室
+func QrToLabWss(w http.ResponseWriter, r *http.Request) {
+	defer qutil.Catch()
+	conn, err := upgrader.Upgrade(w, r, nil)
+	if err != nil {
+		log.Println(err)
+		return
+	}
+	if conn == nil {
+		return
+	}
+	var receive, userId string
+	var qrToLab_ok, qrToLab_open_ok bool
+	//接收消息
+	go func() {
+		defer qutil.Catch()
+		for {
+			//err := websocket.Message.Receive(ws, &receive)
+			_, msgData, err := conn.ReadMessage()
+			//log.Println(string(msgData), "---msgData---:", msgData)
+			receive = string(msgData)
+			if err != nil {
+				receive = "close"
+				//log.Println("websocket接收失败!", err)
+				return
+			}
+			if receive == "close" {
+				return
+			} else if receive != "close" { //接收到userid
+				userId = se.DecodeString(receive)
+			}
+		}
+	}()
+	//发送消息
+	for {
+		time.Sleep(2 * time.Second)
+		if receive == "close" { //接收到关闭信息
+			conn.Close()
+			return
+		} else if userId == "" {
+			continue
+		}
+		var reply string
+		//是否进入实验室
+		if !qrToLab_ok {
+			qrToLab_ok, _ = redis.Exists("other", "qrToLab_"+userId)
+			if qrToLab_ok {
+				reply = "qrToLab_ok"
+			}
+		}
+		//是否打开开关
+		if !qrToLab_open_ok {
+			qrToLab_open_ok, _ = redis.Exists("other", "qrToLab_open_"+userId)
+			if qrToLab_open_ok {
+				reply = "qrToLab_open_ok"
+			}
+		}
+		if reply == "" {
+			continue
+		}
+		sendmessage, _ := json.Marshal(reply)
+		if err := conn.WriteMessage(websocket.TextMessage, sendmessage); err != nil {
+			redis.Del("other", "qrToLab_"+userId)
+			redis.Del("other", "qrToLab_open_"+userId)
+			//log.Println("websocket发送失败!", err)
+			conn.Close()
+			return
+		}
+		if reply == "qrToLab_ok" {
+			redis.Del("other", "qrToLab_"+userId)
+		} else if reply == "qrToLab_open_ok" {
+			redis.Del("other", "qrToLab_open_"+userId)
+		}
+		if qrToLab_ok && qrToLab_open_ok {
+			conn.Close()
+			return
+		}
+	}
+}