Use small program code landing site Online on laptop to realize the function of the article a lot, but given the almost no case, the author implemented today with a small code implementation landing site, experience, address the following idea.techidea8.com/open/idea.s…

Train of thought

The key process

Set the binding relationship between scene sceneid and WebSocket

Get sceneid

The sceneid can be generated at the front end or the back end. You only need to ensure that sceneid is unique at the same time. Front-end generation can be in the form of random number plus time stamp or UUID algorithm

/ / timestamp
var sceneid ="scend-" +  new Data().getTime() + Math.ceil(Math.random()*888888+1000000);
Copy the code

Establish the websocket

var ws = new WebSocket(Ws: / / 192.168.0.106 / websocket?" clientid="+sceneid )
ws.onopen=function(env){
	console.log(env)
} 
ws.onmessage=function(env){
	var data = env.data;
	// This data is the user data sent from the back end
} 

Copy the code

The back end establishes a Websocket

The back-end using the go language github.com/gorilla/websocket package build websocket. Golang is perfect for high-concurrency scenarios.

func (ctrl *PushCtrl) websocket(w http.ResponseWriter, req *http.Request) {

	//fmt.Printf("%+v",request.Header)
	// Todo verifies that the access is valid
	//checkToken(userId int64,token string)
	query := req.URL.Query()
	clientid := query.Get("clientid")

	conn, err := (&websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}).Upgrade(w, req, nil)

	iferr ! =nil {
		log.Println(err.Error())
		return
	}

	clientMap.Store(clientid, conn)
	go func(clientId string, conn *websocket.Conn) {
		// Process the error message
		defer func(a) {
			conn.Close()
			clientMap.Delete(clientid)
		}()
		for {
			_, _, err := conn.ReadMessage()
			iferr ! =nil {
				log.Println(err.Error())
				return
			}
		}
	}(clientid, conn)
}
Copy the code

We use sync.map to establish the corresponding relationship between sceneid and websocket

clientMap.Save(sceneid,conn)
Copy the code

We need to remove the con that is disconnected due to an exception

clientMap.Delete(sceneid)
Copy the code

Get a small program QR code

Get accesstoken of the applet

Small program access request interface as follows’ ‘the interface daily use frequency has a limit, so we need to cache these data, the cache scheme is many, there are redis, there are also memory, we can directly use a variable here to store

accesstoken :=""
func GetAccessToken(a) string{
	return accesstoken 
}
func RefreshAccessToken(a)string{
	url = ""
	resp := httpget(url)
	//resp is a JSON string containing accesstoken
	accesstoken = decodeaccesstokenfromjson(resp)
	return accesstoken 
}
Copy the code

We also need a tick counter to refresh accesstoken,accesstoken is valid for 7200 seconds, we refresh Accesstoken every 4000 seconds

func refreshAccessToken(){
	ticker := time.NewTicker(time.Second *4000)
	for{
		select {
			case <-ticker.C:
				RefreshAccessToken()
		}
	}
}
Copy the code

Start the coroutine in the init method in init.go

go refreshAccessToken()
Copy the code

Small program TWO-DIMENSIONAL code programming skills

Small program interface is as follows: https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESSTOKEN qr code request

Because the link returns two results

Error return Json

{
"errcode":400001."errmsg":"Why? Why?"
}
Copy the code

Returns j image buffer correctly

This is a binary stream, so we need to standardize the return result and we recommend a standardized result

{code:0, data:"", MSG :""}Copy the code
parameter instructions
code Indicates success or failure. 200 indicates success and 400 indicates failure
data Base64 encoding of the image
msg Result description, or error message

An example of this code is as follows

url := fmt.Sprintf("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s", token)
ret, err := util.PostJSON(url, arg)
iferr ! =nil {
		util.FailMsg(w, err.Error())
		return
}

jsonstr := string(ret)
if strings.Contains(jsonstr, "errmsg") {
	util.FailMsg(w, jsonstr)
	return
} else {
	base64data := base64.StdEncoding.EncodeToString(ret)
	util.RespOk(w, "data:image/png; base64,"+base64data)
}
Copy the code

Util is a common toolkit packaged by the author

$("#qrcode").attr("src",res.data)

function refreshqrcode(){
    clientId = "scene-"+new Date().getTime();
    var api = restgo.buildapi("miniapp/getwxacodeunlimit")
    restgo.post(api,{"scene":clientId}).then(res= >{
        if(res.code==200){
            $("#qrcode").attr("src",res.data)
        }else{
            alert(res.msg)    
        }
        intiwebsocket()
    },res=>{
        alert(res.msg)
    })
}
Copy the code

Applets handle key points

Adopt a good framework

We just used Uniapp in the programming process, which is a good framework and is completely vUE grammar. A set of code can generate H5/ small program/Android /ios. We used the watch feature of Vue to determine whether to send information by listening to userID

watch:{
	 userid:function(a,b){
			
			if(a==0) {return 
			}
			
			this.loaddata()
			// If clientid is empty, it is not scanned
			if(!this.clientid){
				return 
			}
// If it is scanned, then we need to push the message to the server back end
server.PublishMsg(this.clientid,this.userid,this.role,this.avatarUrl,this.nickName).then(res= >{
				tip.error(res.msg)
			},res=>{
				tip.error(res.msg)
			})
			
	 }
  }
Copy the code

Get sceneid

We get sceneid through the onload method

onLoad(arg) {
		if(!!!!! arg && !! arg.scene){this.clientid = decodeURIComponent(arg.scene)
		}
				
	},
Copy the code

The core code is as follows

Get the user’s avatar, nickname, and so on from gotUserInfo, and get the code from uni.login

GotUserInfo :function(e) {// Get user avatar, nickname, uni.login({success: res) =>{// get code userinfo.code = res.code from wx.login This.authwithcode (userInfo)}})}}, Authwithcode :function(userInfo){server.authWithCode (userInfo). Then (res=>{ If (res.data.id>0){// If (res.data.id>0){return; } / / if no registration for server RegisterWithOpenId (res) data) mini_openid, the userInfo. AvatarUrl, the userInfo. NickName) #. Then (res = > {/ / registration is returned / / res here. The data is the user object can continue operating}, res = > {tip. The error (res) MSG)})}, res = > {tip. The error (res) MSG | | ""); })}},Copy the code

Experience the address

In this paper, all applications experience address below The Internet industry solution. https://idea.techidea8.com/open/idea.shtml?id=5

About the code

Code get address

Small program code login

Code configuration

Read readme.md carefully