`
xiaoZ5919
  • 浏览: 400974 次
  • 性别: Icon_minigender_1
  • 来自: 安平人@北京
博客专栏
Group-logo
Netty学习笔记
浏览量:72821
社区版块
存档分类
最新评论

基于Netty打造HttpClient实现股票实时推送

阅读更多

   Netty也研究了一段时间,实践是对知识掌握的试金石。有些东西只是看了面儿上的东西我觉得懂了,如不去深入,一旦要用它去做点什么东西却又觉得无从下手。学车的时候,学员问教练我怎么算是学会开车了,教练告诉他当你倒着开和向前开一样自如的时候就算学会了。怎么算掌握了一项技术呢?我的观点,多阅读源码,然后去实践,如此反复,读源码就像倒车。

      为啥用Netty去实现呢?首先提供了Http Codec,支持Http1.0/Http1.1。我们不用再花很大的力气去除encode和decode request和response。和Netty提供的HttpServer相反,我们只需要HttpResponseDecoder和HttpRequestEncoder。我们知道Http协议都是Header-Body。Http1.0通过Content-Length的header来控制body的长度,Http1.1做了一些改进使用chunk的方式编码chunk,通过一个0长度的chunk来标识body的结束。request和response的协议都是Header-body方式的。Netty使用HttpMessageEncoder和HttpMessageDecoder来编码和解码。response和request不同的只是第一行的内容。

       都知道Netty是异步的,这样也带了一个问题,假如我同时在一个channel发送多个request,server也会有多个response过来。如果是同步的,一个请求发送到服务端然后等待response,处理完毕以后接着发送下一个request,如此反复。但是异步就不一样,他同时发送多个request到server而等待服务端的response,那这样我们怎么知道那个request和哪个response是一一对应的呢?针对每一个channel维持一个已发送队列,当发送一个request的时候同时加入到这个队列中,在收到服务端的response从队头中取出一个request即是与之对应的。这样方式看起来是合理的,但还是有潜在的隐患。这种模式和现实浏览器由很大不同,一般是一个connection一次只能用来发送一个request,而不是多个request。假设多个请求的话,服务端是多线程模型,很可能response返回的顺序和request的请求顺序是不一样的。(我的设想没有证明,也许是多虑了,各位看官觉得不对,欢迎指正)

      解决了上面说的问题,一个HttpClient没有多少代码就实现了,同时我用NettyHttpClient抓取新浪的股票数据,再用上次的Comet实现了一个股票实时推送的例子



 

  • 大小: 22.4 KB
0
0
分享到:
评论
8 楼 xiang37 2015-05-13  
兄弟,程序写好了,股票买了没?要是13年买了,那现在就赚大发了。
7 楼 xiaoZ5919 2013-04-24  
liyuanchao2004 写道
发份源码可以吗[/q加uote]  加我qq吧

405919612
6 楼 xiaoZ5919 2013-04-24  
发份源码可以吗[/q加uote]  加我qq吧
5 楼 liyuanchao2004 2013-04-24  
发份源码可以吗
4 楼 xiaoZ5919 2013-01-12  
还是有用处的!起码可以做为异步调用的场景!一个功能依赖多次请求用异步并行加载就比较合适!普通的httpclient要做到异步必须得使用多线程netty用在这儿减少线程的使用数
3 楼 小树鹿鸣 2013-01-12  
xiaoZ5919 写道
恩!断了自动补链接这个好解决,通过channel的isConnected可以判断是否断了。用transactionid维持上下文一般rpc协议设计都是这样用的。用在自己开发的服务还行第三方就不好做到了!如果把channel做成连接池每个channel每次使用只处理一个request,使用完毕以后再放入池中,你觉得这种方案呢A?

现在要解决request与response对应关系,如果做成一个池,就要额外标记channel是否正在使用,这与httpclient 维护http池又有什么区别呢? 还不如用httpclient! 总之要有适合的场景!
2 楼 xiaoZ5919 2013-01-11  
恩!断了自动补链接这个好解决,通过channel的isConnected可以判断是否断了。用transactionid维持上下文一般rpc协议设计都是这样用的。用在自己开发的服务还行第三方就不好做到了!如果把channel做成连接池每个channel每次使用只处理一个request,使用完毕以后再放入池中,你觉得这种方案呢A?
1 楼 小树鹿鸣 2013-01-11  
1.Netty客户端要想高效,就要保持长链接,断了也要自动补链接。
2.服务端是多线程模型,很可能response返回的顺序和request的请求顺序是不一样的。这是肯定的,因此不能用队列去保存,建议采用hash<transactionid:string, Request:HttpClientRequest>, 在httpheader 头部自定义transactionid参数,保证服务端处理完后,头部tansactionid能自带回来!

相关推荐

Global site tag (gtag.js) - Google Analytics