Giter VIP home page Giter VIP logo

Comments (15)

panjf2000 avatar panjf2000 commented on August 18, 2024

See #573

from gnet.

chen2ding avatar chen2ding commented on August 18, 2024
func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
	bodyLen := 0
	ulebLen := 1
	for {
		if ulebLen > 5 {
			break
		}
		buf, err := conn.Peek(ulebLen)
		// 连接中没有数据
		if err != nil || len(buf) != ulebLen {
			return nil, nil
		}
		v := 0
		cc := 0
		for _, b := range buf {
			v += (int(b) & 0x7F) << cc
			cc += 7
			if b&0x80 == 0 {
				bodyLen = v
				break
			}
		}
		// uleb 读取完整退出循环
		if bodyLen > 0 {
			break
		}
		ulebLen++
	}
	defer conn.Discard(bodyLen + ulebLen)
	//等待读取bodyLen
	if bodyLen > uc.readBuffSize {
		return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
	}
	buf, _ := conn.Peek(ulebLen + bodyLen)
	//PrintHex(buf[ulebLen:])
	return buf[ulebLen:], nil
} 

同样的代码v1升级V2后不能正常工作上面是V2代码下面v1

func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
	bodyLen := 0
	ulebLen := 1
	for {
		if ulebLen > 5 {
			break
		}
		n, buf := conn.ReadN(ulebLen)
		// 连接中没有数据
		if n == 0 || n != ulebLen {
			return nil, nil
		}
		v := 0
		cc := 0
		for _, b := range buf {
			v += (int(b) & 0x7F) << cc
			cc += 7
			if b&0x80 == 0 {
				bodyLen = v
				break
			}
		}
		// uleb 读取完整退出循环
		if bodyLen > 0 {
			break
		}
		ulebLen++
	}
	defer conn.ShiftN(bodyLen + ulebLen)
	//等待读取bodyLen
	if bodyLen > uc.readBuffSize {
		return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
	}
	_, buf := conn.ReadN(ulebLen + bodyLen)
	return buf[ulebLen:], nil
}

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
ifulebLen > 5 {
break
}
buf, err := conn.Peek(ulebLen)
// There is no data in the connection
if err != nil || len(buf) != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb reads completely and exits the loop
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.Discard(bodyLen + ulebLen)
//Waiting to read bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
buf, _ := conn.Peek(ulebLen + bodyLen)
//PrintHex(buf[ulebLen:])
return buf[ulebLen:], nil
} The same code, v1 cannot work properly after upgrading to V2. The above is the V2 code, and the following v1

func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
ifulebLen > 5 {
break
}
n, buf := conn.ReadN(ulebLen)
// There is no data in the connection
if n == 0 || n != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb reads completely and exits the loop
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.ShiftN(bodyLen + ulebLen)
//Waiting to read bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
_, buf := conn.ReadN(ulebLen + bodyLen)
return buf[ulebLen:], nil
}

from gnet.

chen2ding avatar chen2ding commented on August 18, 2024

@panjf2000 请问这是什么问题呢

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


@panjf2000 What is the problem?

from gnet.

chen2ding avatar chen2ding commented on August 18, 2024

@panjf2000 调试感觉是buf中的数据我没有读完,然后后面就不触发OnTraffic了,v1版本正常的

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


@panjf2000 The debugging feeling is that I haven’t finished reading the data in buf, and then OnTraffic will not be triggered later. The v1 version is normal.

from gnet.

panjf2000 avatar panjf2000 commented on August 18, 2024

First format your code, it's unreadable.

from gnet.

chen2ding avatar chen2ding commented on August 18, 2024

@panjf2000 已经格式化了,麻烦看下上面代码呢

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


@panjf2000 It has been formatted. Please take a look at the above code.

from gnet.

panjf2000 avatar panjf2000 commented on August 18, 2024

One of the best practices with gnet v2 is to keep reading and decoding packets until you reach an incomplete packet, otherwise the OnTraffic won't be invoked again until there is new arrival of data on the socket. I think the root cause of your issue here is that gnet v1 would loop reading and decoding packets internally while gnet v2 wouldn't.

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


One of the best practices with v2 gnet is to continue reading and decoding packets until an incomplete packet arrives, otherwise not calling OnTraffic again until new data arrives on the socket. I think the root cause of your problem is that gnetv1 internally loops reading and decoding packets, while gnetv2 does not.

I can confirm that the v1 version is not reading in the inner loop, the decode code is above
This is the V1 outer code

func (s *Server) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) {
msg := BinaryJson.DecodeGJson(frame)
if msg == nil {
action = gnet.Close
return
}
client, ok := c.Context().(*Client)
if !ok || client == nil {
return
}
task := func() {
msgType, _ := msg.GetInt("t")
switch msgType {
case rpc.PingMsg:
if err := s.Codec.WriteULEB128(client.Conn, rpc.NewPingResp()); err != nil {
client.Close()
}
client.UpdateLastPingTime()
case rpc.PongMsg:
case rpc.ReqMsg, rpc.PushMsg:
req := &rpc.Req{}
req.FromGJson(msg)
if req.Param == nil {
return
}
resp := s.Handler.HandleReq(client, req)
// Requests that do not require a reply will not be processed if the response is obtained.
if resp == nil {
return
}
// Determine whether it is an error response message
if _, ok := msg.GetString("e"); ok {
client.Close() // Wrong response information, actively close the connection
return
}
if _, ok := msg.GetString("ec"); ok {
client.Close() // Wrong response information, actively close the connection
return
}
if err := s.Codec.WriteULEB128(client.Conn, resp); err != nil {
client.Close()
}
case rpc.RespMsg:
resp := &rpc.Resp{}
resp.FromGJson(msg)
s.Handler.HandleResp(client, resp)
default:
xlog.Ins.Error(s.Handler.Name(), zap.Error(fmt.Errorf("Unknown message type: %d", msgType)))
}
}
_ = s.pool.Submit(task)
return
}

from gnet.

panjf2000 avatar panjf2000 commented on August 18, 2024

https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126

from gnet.

chen2ding avatar chen2ding commented on August 18, 2024

https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126

哦哦,了解

from gnet.

gh-translator avatar gh-translator commented on August 18, 2024

🤖 Non-English text detected, translating...


https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126

Oh, I understand

from gnet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.