示例#1
0
func (self *Client) chgESTABLISHED(pb *pushproto.Talk) {
	fun := "Client.chgESTABLISHED"
	self.state_lock.Lock()
	defer self.state_lock.Unlock()

	if self.state == State_ESTABLISHED {
		// 已经建立了连接,当前状态是ESTABLISHED,可能是客户端没有收到synack
		// 重新回执synack

		slog.Warnf("%s client:%s is already:%s", fun, self, State_ESTABLISHED)
		self.sendSYNACK(self.client_id)
		return
	}

	appid := pb.GetAppid()
	installid := pb.GetInstallid()
	sec := "9b0319bc5c05055283cee2533abab270"

	h := sha1.Sum([]byte(appid + installid + sec))
	self.client_id = fmt.Sprintf("%x", h)

	old_state := self.state
	self.state = State_ESTABLISHED

	slog.Infof("%s change client:%s %s:%s", fun, self, old_state, self.state)

	self.sendSYNACK(self.client_id)
	self.manager.addClient(self)

}
示例#2
0
func (self *Client) dochgCLOSED(isRmManager bool) {
	fun := "Client.dochgCLOSED"
	self.state_lock.Lock()
	defer self.state_lock.Unlock()

	if self.state == State_CLOSED {
		slog.Warnf("%s client:%s is already:%s", fun, self, State_CLOSED)
		return
	}

	if isRmManager && self.state == State_ESTABLISHED {
		self.manager.delClient(self.client_id, self.remoteaddr)
	}

	if err := self.conn.Close(); err != nil {
		slog.Warnf("%s client:%s Close net.Conn err: %s", fun, self, err)
	}

	for k, v := range self.bussmsg {
		select {
		case v <- false:
		default:
			slog.Warnf("%s client:%s msgid:%d no wait notify", fun, self, k)
		}
	}

	old_state := self.state
	self.state = State_CLOSED

	slog.Infof("%s change client:%s %s:%s", fun, self, old_state, self.state)

}
示例#3
0
func (self *ConnectionManager) Loop(addr string) {
	fun := "ConnectionManager.Loop"

	tcpAddr, error := net.ResolveTCPAddr("tcp", addr)
	if error != nil {
		slog.Fatalf("%s Error: Could not resolve address %s", fun, error)
		panic("resolve address")
	}

	netListen, error := net.Listen(tcpAddr.Network(), tcpAddr.String())
	if error != nil {
		slog.Fatalf("%s Error: Could not Listen %s", fun, error)
		panic("listen address")

	}
	defer netListen.Close()

	//go self.req()
	//go self.trans()

	for {
		slog.Infof("%s Waiting for clients", fun)
		connection, error := netListen.Accept()
		if error != nil {
			slog.Warnf("%s Client error: ", fun, error)
		} else {
			NewClient(self, connection)
		}
	}

}
示例#4
0
func (self *Client) SendBussiness(ziptype int32, datatype int32, data []byte) (uint64, string) {
	fun := "Client.SendBussiness"

	msgid, err := self.manager.Msgid()
	if err != nil {
		slog.Errorf("%s get msgid error:%s", fun, err)
		return 0, self.remoteaddr
	}

	buss := &pushproto.Talk{
		Type:     pushproto.Talk_BUSSINESS.Enum(),
		Msgid:    proto.Uint64(msgid),
		Ziptype:  proto.Int32(ziptype),
		Datatype: proto.Int32(datatype),
		Bussdata: data,
	}

	spb, err := proto.Marshal(buss)
	if err != nil {
		slog.Errorf("%s marshaling error: ", fun, err)
		return 0, self.remoteaddr
	}

	p := util.Packdata(spb)
	self.sendBussRetry(msgid, p)

	slog.Infof("%s client:%s send msgid:%d", fun, self, msgid)
	self.Send(p)

	return msgid, self.remoteaddr
}
示例#5
0
func (self *Client) sendBussRetry(msgid uint64, pb []byte) {
	fun := "Client.sendBussRetry"
	ack_notify := make(chan bool)

	self.addBussmsg(msgid, ack_notify)

	retry_intv := 2
	retry_time := 3

	go func() {
		defer self.rmBussmsg(msgid)

		for i := 1; i <= retry_time+1; i++ {

			select {
			case v := <-ack_notify:
				if v {
					slog.Infof("%s client:%s recv ack msgid:%d", fun, self, msgid)
				} else {
					slog.Infof("%s client:%s close not recv ack msgid:%d", fun, self, msgid)
				}
				return

			case <-time.After(time.Second * time.Duration(retry_intv)):
				if i <= retry_time {
					slog.Infof("%s client:%s retry msgid:%d times:%d", fun, self, msgid, i)
					self.Send(pb)
				} else {
					// 最后一次发送已经超时
					slog.Infof("%s client:%s send timeout msgid:%d", fun, self, msgid)
					// 断开连接
					self.chgCLOSED()
					return

				}

			}

			retry_intv = retry_intv << 1

		}

	}()

}
示例#6
0
func (self *ConnectionManager) addClient(cli *Client) {
	fun := "ConnectionManager.addClient"

	client_id := cli.client_id
	if v, ok := self.clients[client_id]; ok {
		v.errNotifyCLOSED("dup client add client")
		delete(self.clients, client_id)
		slog.Warnf("%s dup client add client_id %s", fun, client_id)

	}
	self.clients[client_id] = cli
	slog.Infof("%s Add %s %d", fun, cli, len(self.clients))

}
示例#7
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)

}
示例#8
0
func (self *ConnectionManager) delClient(client_id string, addr string) {
	fun := "ConnectionManager.delClient"
	if v, ok := self.clients[client_id]; ok {
		if v.remoteaddr == addr {
			delete(self.clients, client_id)
			slog.Infof("%s Remove %s %d", fun, v, len(self.clients))
		} else {
			slog.Warnf("%s delete client %s not same %s", fun, v, addr)
		}

	} else {
		slog.Warnf("%s delete client_id %s not fond", fun, client_id)
	}

}
示例#9
0
func main() {
	cfg := config{ServId: 0, HttpServ: ":9091", ConnServ: ":9989"}

	js, _ := json.Marshal(&cfg)

	slog.Init(os.Stdout)

	slog.Infof("%s", js)

	conn_man := connection.NewConnectionManager()

	httpport := ":9091"
	connection.StartHttp(conn_man, httpport)

	service := ":9989"
	conn_man.Loop(service)

}
示例#10
0
// goroutine
func (self *Client) sendData(s []byte, isclose bool) {
	fun := "Client.sendData"
	//slog.Debug("sendData %s %d", s, isclose)
	self.send_lock.Lock()
	defer self.send_lock.Unlock()

	self.conn.SetWriteDeadline(time.Now().Add(time.Duration(5) * time.Second))
	a, err := self.conn.Write(s)
	slog.Infof("%s client:%s Send Write rv %d", fun, self, a)

	if err != nil {
		slog.Warnf("%s client:%s write error:%s ", fun, self, err)
		self.chgCLOSED()
		return
	}

	if isclose {
		self.chgCLOSED()
	}

}
示例#11
0
func (self *Client) chgCLOSED2TCP_READY(c net.Conn) {
	fun := "Client.chgCLOSED2TCP_READY"
	self.state_lock.Lock()
	defer self.state_lock.Unlock()

	if self.state == State_TCP_READY {
		slog.Warnf("%s client:%s is already:%s", fun, self, State_TCP_READY)
		return
	}

	self.client_id = "NULL"
	self.conn = c
	self.remoteaddr = c.RemoteAddr().String()
	self.bussmsg = make(map[uint64]chan bool)

	old_state := self.state
	self.state = State_TCP_READY

	slog.Infof("%s change client:%s %s:%s", fun, self, old_state, self.state)

	go self.Recv()
}
示例#12
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

			}

		}

	}

}