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

websocket http header保存 #33

Closed
Allenxuxu opened this issue Apr 14, 2020 · 8 comments
Closed

websocket http header保存 #33

Allenxuxu opened this issue Apr 14, 2020 · 8 comments

Comments

@Allenxuxu
Copy link
Owner

websocket升级的时候需要把http header保存下来的,里面的数据后面conn处理请求要用到的,现在看起来没法做到,需要修改框架支持,

Originally posted by @lyfunny in #4 (comment)

@Allenxuxu
Copy link
Owner Author

这是一个特性需求,我把 issue 移到这里。

目前 websocket 插件支持还不够完善。
不过插件和 gev 框架是分开的,修改 websocket 相关部分就好了。
通过 connection 的 Context 保存 header ,似乎改动不大。

func (c *Connection) SetContext(ctx interface{}) {
	c.ctx = ctx
}

https://github.com/Allenxuxu/gev/tree/master/plugins/websocket

@Allenxuxu Allenxuxu changed the title websocket升级的时候需要把http header保存下来的,里面的数据后面conn处理请求要用到的,现在看起来没法做到,需要修改框架支持, websocket http header保存 Apr 14, 2020
@ghost
Copy link

ghost commented Apr 14, 2020

这个EventLoop中的onMessage执行是同步的,如果里面有网络调用,会阻塞EventLoop,生成一个gorutine执行的话返回消息有发送不了了,websocket Send没法用

@MrChang0
Copy link

这个EventLoop中的onMessage执行是同步的,如果里面有网络调用,会阻塞EventLoop,生成一个gorutine执行的话返回消息有发送不了了,websocket Send没法用

网络调用为什么会阻塞EventLoop?

@ghost
Copy link

ghost commented Apr 14, 2020

这个EventLoop中的onMessage执行是同步的,如果里面有网络调用,会阻塞EventLoop,生成一个gorutine执行的话返回消息有发送不了了,websocket Send没法用

网络调用为什么会阻塞EventLoop?

我的cpu32核心,eventloop是由32个goroutine执行的,当执行到OnMessage的时候,如果发生网络调用,那么这个goroutine就休眠了,那么就没有goroutine执行eventloop了,没法处理到来的请求了.现在我是在OnMessage里面新生成一个goroutine执行业务的,缺点就是返回数据需要用Send调用,OnMessage的返回值没用

@Allenxuxu
Copy link
Owner Author

这个EventLoop中的onMessage执行是同步的,如果里面有网络调用,会阻塞EventLoop,生成一个gorutine执行的话返回消息有发送不了了,websocket Send没法用

网络调用为什么会阻塞EventLoop?

我的cpu32核心,eventloop是由32个goroutine执行的,当执行到OnMessage的时候,如果发生网络调用,那么这个goroutine就休眠了,那么就没有goroutine执行eventloop了,没法处理到来的请求了.现在我是在OnMessage里面新生成一个goroutine执行业务的,缺点就是返回数据需要用Send调用,OnMessage的返回值没用

不应该在 OnMessage 做耗时的操作,如果比较耗时,最好只在 OnMessage 里切割数据,然后使用 Send 发送。

@Allenxuxu
Copy link
Owner Author

@lyfunny 考虑 在 gev 里增加一个协程池, OnMessage 函数放到协程池中执行。

@Allenxuxu
Copy link
Owner Author

Allenxuxu commented Apr 16, 2020

https://github.com/Allenxuxu/gev/blob/master/example/websocket/main.go

websocke 增加了取 header 的例子 @lyfunny

func main() {
//....

	wsUpgrader := &ws.Upgrader{}
	wsUpgrader.OnHeader = func(c *connection.Connection,key, value []byte) error {
		fmt.Println(string(key),":" ,string(value))

              // 这个回调函数会在 协议升级成功被调用
              // 在这里可以将需要的 header 保存起来,通过 c.SetContext 方法

		return nil
	}

	s, err := NewWebSocketServer(handler, wsUpgrader,
		gev.Network("tcp"),
		gev.Address(":"+strconv.Itoa(port)),
		gev.NumLoops(loops))
	if err != nil {
		panic(err)
	}

	s.Start()
}

@yiippee
Copy link

yiippee commented Sep 25, 2020

https://github.com/Allenxuxu/gev/blob/master/example/websocket/main.go

websocke 增加了取 header 的例子 @lyfunny

func main() {
//....

	wsUpgrader := &ws.Upgrader{}
	wsUpgrader.OnHeader = func(c *connection.Connection,key, value []byte) error {
		fmt.Println(string(key),":" ,string(value))

              // 这个回调函数会在 协议升级成功被调用
              // 在这里可以将需要的 header 保存起来,通过 c.SetContext 方法

		return nil
	}

	s, err := NewWebSocketServer(handler, wsUpgrader,
		gev.Network("tcp"),
		gev.Address(":"+strconv.Itoa(port)),
		gev.NumLoops(loops))
	if err != nil {
		panic(err)
	}

	s.Start()
}

这样设置好像没用啊,你在这里设置为true了

		out, _, err = p.upgrade.Upgrade(c, buffer)
		if err != nil {
			log.Error("Websocket Upgrade :", err)
			return
		}
		c.SetContext(true)        // 设置为true,标志已经upgrade过了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants