示例#1
0
func (self *Client) proto(data []byte) {
	fun := "Client.proto"
	pb := &pushproto.Talk{}
	err := proto.Unmarshal(data, pb)
	if err != nil {
		slog.Warnf("%s unmarshaling error: %s", fun, err)
		self.errNotifyCLOSED("package unmarshaling error")
		return
	}

	slog.Debugf("%s recv proto: %s", fun, pb)
	pb_type := pb.GetType()

	if pb_type == pushproto.Talk_SYN {
		self.recvSYN(pb)
	} else if pb_type == pushproto.Talk_ECHO {
		self.Send(util.Packdata(data))

	} else if pb_type == pushproto.Talk_HEART {
		self.sendHEART()

	} else if pb_type == pushproto.Talk_ACK {
		self.recvACK(pb)

	}

}
示例#2
0
func (self *Client) errNotifyCLOSED(errmsg string) {
	fun := "Client.errNotifyCLOSED"
	//slog.Debug("errmsg:%s", errmsg)
	errpb := &pushproto.Talk{
		Type:    pushproto.Talk_ERR.Enum(),
		Extdata: []byte(errmsg),
	}

	slog.Debugf("%s errmsg:%s", fun, errpb)
	data, _ := proto.Marshal(errpb)
	self.SendClose(util.Packdata(data))

}
示例#3
0
// Method: POST
// Uri: /push/CLIENT_ID/ZIPTYPE/DATATYPE
// Data: push data
func push(w http.ResponseWriter, r *http.Request) {
	fun := "rest.push"
	//debug_show_request(r)
	if r.Method != "POST" {
		writeRestErr(w, "method err")
		return
	}

	slog.Infof("%s %s", fun, r.URL.Path)
	path := strings.Split(r.URL.Path, "/")
	//slog.Info("%q", path)

	if len(path) != 5 {
		writeRestErr(w, "uri err")
		return
	}

	// path[0] "", path[1] push
	clientid := path[2]

	ziptype, err := strconv.Atoi(path[3])
	if err != nil {
		writeRestErr(w, "ziptype err")
		return
	}

	datatype, err := strconv.Atoi(path[4])
	if err != nil {
		writeRestErr(w, "datatype err")
		return
	}

	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		writeRestErr(w, "data err")
		return
	}

	if len(data) == 0 {
		writeRestErr(w, "data empty")
		return
	}

	msgid, link := connman.Send(clientid, int32(ziptype), int32(datatype), data)
	slog.Debugf("%s msgid:%d link:%s", fun, msgid, link)
	js, _ := json.Marshal(&RestReturn{Code: 0, Msgid: msgid, Link: link})
	fmt.Fprintf(w, "%s", js)

}
示例#4
0
func (self *Client) recvACK(pb *pushproto.Talk) {
	fun := "Client.recvACK"

	msgid := pb.GetAckmsgid()

	c := self.getBussmsg(msgid)

	if c != nil {
		select {
		case c <- true:
			slog.Debugf("%s client:%s msgid:%d notify", fun, self, msgid)
		default:
			slog.Warnf("%s client:%s msgid:%d no wait notify", fun, self, msgid)
		}
	} else {
		slog.Warnf("%s client:%s msgid:%d not found", fun, self, msgid)
	}

}
示例#5
0
// goroutine
func (self *Client) Recv() {
	fun := "Client.Recv"
	buffer := make([]byte, 2048)
	packBuff := make([]byte, 0)
	var bufLen uint64 = 0

	conn := self.conn
	errmsg := ""
	defer self.deferErrNotifyCLOSED(&errmsg)

	for {
		conn.SetReadDeadline(time.Now().Add(time.Duration(60*10) * time.Second))
		bytesRead, error := conn.Read(buffer)
		if error != nil {
			slog.Infof("%s client:%s conn error: %s", fun, self, error)
			return
		}

		packBuff = append(packBuff, buffer[:bytesRead]...)
		bufLen += uint64(bytesRead)

		slog.Infof("%s client:%s Recv: %d %d %d", fun, self, bytesRead, packBuff, bufLen)

		for {
			if bufLen > 0 {
				pacLen, sz := binary.Uvarint(packBuff[:bufLen])
				if sz < 0 {
					slog.Warnf("%s client:%s package head error:%s", fun, self, packBuff[:bufLen])
					return
				} else if sz == 0 {
					break
				}

				slog.Debugf("%s pacLen %d", fun, pacLen)
				// must < 5K
				if pacLen > 1024*5 {
					slog.Warnf("%s client:%s package too long error:%s", fun, self, packBuff[:bufLen])
					errmsg = "package too long"
					return
				} else if pacLen == 0 {
					errmsg = "package len 0"
					return
				}

				apacLen := uint64(sz) + pacLen + 1
				if bufLen >= apacLen {
					pad := packBuff[apacLen-1]
					if pad != 0 {
						slog.Warnf("%s client:%s package pad error:%s", fun, self, packBuff[:bufLen])
						errmsg = "package pad error"
						return
					}
					self.proto(packBuff[sz : apacLen-1])
					packBuff = packBuff[apacLen:]
					bufLen -= apacLen
				} else {
					break
				}

			} else {
				break

			}

		}

	}

}