gnet icon indicating copy to clipboard operation
gnet copied to clipboard

服务端能不能添加接口, 可以主动向客户端发送消息

Open cham-pin opened this issue 3 years ago • 8 comments

目前的接口都是通过React接收消息 然后返回结果给客户端 如果server想主动发消息给客户端呢 目前我看只有UDP模式下有SendTO方法

一个场景:

  1. 客户端询问server执行结果并等待返回, 如果服务端没有处理完, 则需要for sleep操作, 这样就可能有几十微秒(30-50)的延迟
  2. 如果server可以主动向客户端发送消息, 则服务端处理完成后直接告诉客户端结果, 客户端就无须主动询问
  3. 上述的优化, 可以节省一次网络请求, 以及可能的几十微秒的处理延迟

cham-pin avatar Mar 10 '21 03:03 cham-pin

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

xscode-auto-reply[bot] avatar Mar 10 '21 03:03 xscode-auto-reply[bot]

https://github.com/gnet-io/gnet-examples/blob/master/examples/push/push.go

panjf2000 avatar Mar 10 '21 06:03 panjf2000

https://github.com/gnet-io/gnet-examples/blob/master/examples/push/push.go 我可能更需要直接调用 func (c *conn) write(buf []byte) (err error) 这个方法 异步的可能对延迟有一定影响

cham-pin avatar Mar 10 '21 06:03 cham-pin

https://github.com/gnet-io/gnet-examples/blob/master/examples/push/push.go

由于我走的域通信, 网络只是用来传输消息头, 然后通过共享内存实现消息的通信. 所以网络传输量不多, 但是很频繁

cham-pin avatar Mar 10 '21 06:03 cham-pin

https://github.com/gnet-io/gnet-examples/blob/master/examples/push/push.go 我可能更需要直接调用 func (c *conn) write(buf []byte) (err error) 这个方法 异步的可能对延迟有一定影响

因为目前 conn 是没有锁保护的,因此所有相关的操作都会放到单 goroutine 里执行以确保没有 data race,所以不能直接调用 c.write.

panjf2000 avatar Mar 10 '21 13:03 panjf2000

理解, 既然unix域通信无法获取RemoteAddr, 那么能不能添加获取fd的方法, 这样我就能map了

cham-pin avatar Mar 11 '21 02:03 cham-pin

在外部拿到conn后不能直接调用c.AsyncWrite方法吗? 我的业务场景是broker收到客户端的消息发给mq, 收到mq的消息找到conn,然后直接调用c.AsyncWrite发给客户端。

chowyu08 avatar Mar 11 '21 03:03 chowyu08

在外部拿到conn后不能直接调用c.AsyncWrite方法吗? 我的业务场景是broker收到客户端的消息发给mq, 收到mq的消息找到conn,然后直接调用c.AsyncWrite发给客户端。

看代码是可以这么做的,因为添加task是通过cas操作的,是线程安全的

	n := &node{value: task}
loop:
	tail := load(&q.tail)
	next := load(&tail.next)
	// Are tail and next consistent?
	if tail == load(&q.tail) {
		if next == nil {
			// Try to link node at the end of the linked list.
			if cas(&tail.next, next, n) {
				// Enqueue is done. Try to swing tail to the inserted node.
				cas(&q.tail, tail, n)
				atomic.AddInt32(&q.len, 1)
				return
			}
		} else { // tail was not pointing to the last node
			// Try to swing Tail to the next node.
			cas(&q.tail, tail, next)
		}
	}
	goto loop
}```

ependi-buzz avatar Jun 29 '21 09:06 ependi-buzz