Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用 gnet 做游戏网关,广播消息的场景 #236

Open
zklscut opened this issue Jul 28, 2021 · 5 comments
Open

用 gnet 做游戏网关,广播消息的场景 #236

zklscut opened this issue Jul 28, 2021 · 5 comments
Assignees
Labels
help wanted Extra attention is needed question Further information is requested waiting for response waiting for the response from commenter

Comments

@zklscut
Copy link

zklscut commented Jul 28, 2021

2000 个连接,每10 秒通过远端服务器向其他连接广播一条消息,大小 1K 左右
实际测试下来与直接转发效率差了 25%左右
后来也使用了 https://github.com/calbot/gnet.git来管理gnet与服务器的连接,发现性能依旧是降低的
不太适合这个场景?还是使用有问题

func (es *echoServer) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) {
	data := append([]byte{}, frame...)
	_ = es.pool.Submit(func() {
		s, ok := serverMap.Load(c.RemoteAddr().String())
		if ok {
			serverConn := s.(net.Conn)
			serverConn.Write(data)
		}
	})

	return
}
func (es *echoServer) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) {
	serverConn, _ := net.Dial("tcp", serverAddr)
	serverMap.Store(c.RemoteAddr().String(), serverConn)

	go func() {
		b := make([]byte, 2048)
		for {
			size, err := serverConn.Read(b)
			if err != nil {
				break
			}
			c.AsyncWrite(b[0:size])
		}
	}()
	return
}
func test() {
	l, _ := net.Listen("tcp", "127.0.0.1:6060")
	defer l.Close()
	go func() {
		for {
			clientConn, _ := l.Accept()
			serverConn, _ := net.Dial("tcp", "127.0.0.1:6061")
			go func() {
				b := make([]byte, 2048)
				for {
					size, err := serverConn.Read(b)
					if err != nil {
						break
					}
					if size > 0 {
						clientConn.Write(b[0:size])
					}
				}
			}()

			go func() {
				b := make([]byte, 2048)
				for {
					size, err := clientConn.Read(b)
					if err != nil {
						break
					}
					if size > 0 {
						serverConn.Write(b[0:size])
					}
				}
			}()
		}
	}()
}
@zklscut zklscut added help wanted Extra attention is needed question Further information is requested labels Jul 28, 2021
@xscode-auto-reply
Copy link

Thanks for opening a new issue. The team has been notified and will review it as soon as possible.
For urgent issues and priority support, visit https://xscode.com/panjf2000/gnet

@panjf2000
Copy link
Owner

panjf2000 commented Jul 28, 2021

gnet 哪个版本?还有为什么要用 goroutine pool? React() 直接写不就行了?

@panjf2000
Copy link
Owner

panjf2000 commented Jul 28, 2021

你这种用法只用了 gnet 的异步任务队列的功能,gnet 管理的每一个 socket 要依赖于另外一个 socket 的响应,所以每一个 gnet 的 socket 回写数据的时候是先放到异步队列,然后通过系统调用,唤醒 epoll 所在的线程去 Write 数据,当然不如用标准库直接 Write 了。

gnet 不太适合你这种场景。

@panjf2000 panjf2000 added the waiting for response waiting for the response from commenter label Jul 28, 2021
@zklscut
Copy link
Author

zklscut commented Jul 29, 2021

你这种用法只用了 gnet 的异步任务队列的功能,gnet 管理的每一个 socket 要依赖于另外一个 socket 的响应,所以每一个 gnet 的 socket 回写数据的时候是先放到异步队列,然后通过系统调用,唤醒 epoll,当然不如用标准库直接 Write 了。

gnet 不太适合你这种场景。

谢谢解答,另外关于这种场景有什么优化建议么?对应的项目是游戏内的战斗广播,1000 人集中在一个点上互相广播消息。包的大小从500B 到 10K 不等,gnet在这里只负责转发两侧的消息。
尝试了几种优化方案都不太理想。

@Chairou
Copy link

Chairou commented Jul 29, 2021 via email

@panjf2000 panjf2000 changed the title 使用gnet做网关转发时,性能不如直接创建Groutine处理? 用 gnet 做游戏网关,广播消息的场景 Jul 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested waiting for response waiting for the response from commenter
Projects
None yet
Development

No branches or pull requests

3 participants