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

Closed
zklscut opened this issue Jul 28, 2021 · 9 comments
Closed

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

zklscut opened this issue Jul 28, 2021 · 9 comments
Assignees
Labels
help wanted Extra attention is needed question Further information is requested stale 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
@ckcfcc
Copy link

ckcfcc commented Aug 25, 2024

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

如果是很频繁的一个小区域内1000人同时相互广播,比如1秒内,1000人都需要广播消息,那量比较大 1000 * 1000 次通讯 每次最小按500 byte算,有大概476.837MB的数据要收发,感觉啥库都可能会不理想吧

@gh-translator
Copy link
Collaborator

🤖 Non-English text detected, translating...


Thank you for your answer. Do you have any optimization suggestions for this scenario? The corresponding project is the in-game battle broadcast, where 1,000 people gather at one point to broadcast messages to each other. The size of the packet ranges from 500B to 10K, and gnet is only responsible for forwarding messages on both sides here.
Tried several optimization solutions but none were ideal.

If it is very frequent that 1,000 people in a small area broadcast to each other at the same time, for example, within 1 second, 1,000 people need to broadcast messages, the amount is relatively large, 1000 * 1000 times of communication, each time is calculated as a minimum of 500 bytes, and there is about 476.837MB of data required. For sending and receiving, I feel that any library may not be ideal.

Copy link

This issue is marked as stale because it has been open for 30 days with no activity.

You should take one of the following actions:

  • Manually close this issue if it is no longer relevant
  • Comment if you have more information to share

This issue will be automatically closed in 7 days if no further activity occurs.

@github-actions github-actions bot added the stale label Sep 26, 2024
Copy link

github-actions bot commented Oct 4, 2024

This issue was closed because it has been inactive for 7 days since being marked as stale.

If you believe this is a false alarm, please leave a comment for it or open a new issue, you can also reopen this issue directly if you have permission.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 4, 2024
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 stale waiting for response waiting for the response from commenter
Projects
None yet
Development

No branches or pull requests

5 participants