コード例 #1
0
ファイル: client.go プロジェクト: shawnfeng/code_tst
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)

}
コード例 #2
0
ファイル: connmanager.go プロジェクト: shawnfeng/code_tst
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)
	}

}
コード例 #3
0
ファイル: client.go プロジェクト: shawnfeng/code_tst
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)

}
コード例 #4
0
ファイル: connmanager.go プロジェクト: shawnfeng/code_tst
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)
		}
	}

}
コード例 #5
0
ファイル: proto.go プロジェクト: shawnfeng/code_tst
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)

	}

}
コード例 #6
0
ファイル: proto.go プロジェクト: shawnfeng/code_tst
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)
	}

}
コード例 #7
0
ファイル: connmanager.go プロジェクト: shawnfeng/code_tst
func (self *ConnectionManager) Send(client_id string, ziptype int32, datatype int32, data []byte) (uint64, string) {
	fun := "ConnectionManager.Send"
	if v, ok := self.clients[client_id]; ok {
		return v.SendBussiness(ziptype, datatype, data)

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

}
コード例 #8
0
ファイル: connmanager.go プロジェクト: shawnfeng/code_tst
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))

}
コード例 #9
0
ファイル: client.go プロジェクト: shawnfeng/code_tst
// 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()
	}

}
コード例 #10
0
ファイル: client.go プロジェクト: shawnfeng/code_tst
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()
}
コード例 #11
0
ファイル: client.go プロジェクト: shawnfeng/code_tst
// 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

			}

		}

	}

}