重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
我们在mian函数中,首先初始化配置文件,然后新建http连接。
在清水等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站建设、成都网站建设 网站设计制作按需设计,公司网站建设,企业网站建设,品牌网站设计,营销型网站,成都外贸网站建设,清水网站建设费用合理。
这个连接创建之后,监听服务器的9999端口。如果url的路径后缀为 "/ws",就转发到ws/ws.go中的IndexHandler方法中。
这个方法中首先我们创建一个websocket的Upgrader实例,然后我们使用Upgrader的upgrade方法来升级一下我们的连接为长连接。
升级完成之后会返回一个*websocket.Conn的连接,我们之后所有的关于连接的操作,都是基于该conn的。
在该连接完成之后,我们将连接存放到一个名为Client的map中,以便之后管理更为方便。
之后,我们启动一个goroutine来读取连接中发送的信息内容,再根据内容进行相应的操作。
学完了 net/http 和 fasthttp 两个HTTP协议接口的客户端实现,接下来就要开始Server的开发,不学不知道一学吓一跳,居然这两个库还支持Server的开发,太方便了。
相比于Java的HTTPServer开发基本上都是使用Spring或者Springboot框架,总是要配置各种配置类,各种 handle 对象。Golang的Server开发显得非常简单,就是因为特别简单,或者说没有形成特别统一的规范或者框架,我发现了很多实现方式,HTTP协议基于还是 net/http 和 fasthttp ,但是 handle 语法就多种多样了。
先复习一下: Golang语言HTTP客户端实践 、 Golang fasthttp实践 。
在Golang语言方面,实现某个功能的库可能会比较多,有机会还是要多跟同行交流,指不定就发现了更好用的库。下面我分享我学到的六种Server开发的实现Demo。
基于 net/http 实现,这是一种比较基础的,对于接口和 handle 映射关系处理并不优雅,不推荐使用。
第二种也是基于 net/http ,这种编写语法可以很好地解决第一种的问题,handle和path有了类似配置的语法,可读性提高了很多。
第三个基于 net/http 和 github点抗 /labstack/echo ,后者主要提供了 Echo 对象用来处理各类配置包括接口和handle映射,功能很丰富,可读性最佳。
第四种依然基于 net/http 实现,引入了 github点抗 /gin-gonic/gin 的路由,看起来接口和 handle 映射关系比较明晰了。
第五种基于 fasthttp 开发,使用都是 fasthttp 提供的API,可读性尚可,handle配置倒是更像Java了。
第六种依然基于 fasthttp ,用到了 github点抗 /buaazp/fasthttprouter ,有点奇怪两个居然不在一个GitHub仓库里。使用语法跟第三种方式有点类似,比较有条理,有利于阅读。
golang net/http标准库的client是可以配置各种代理的,http/https/sock5等,不过fasthttp仅支持配置sock5代理,通过定义fasthttp dialfunc实现:
项目中碰到的问题是,ops只提供了用squid搭建的http代理,所以是想重新定义一个http代理的dialfunc,找了fasthttp github仓库的issue,作者提供了一个dialFunc
经测试,访问https的站点是OK的,访问http的站点不行,代理连接不上。先说一下http/https代理的区别,再说原因。
使用代理访问https网站时,会先发CONNECT请求,让代理与目标站点建立一个http tunnel,之后在这个tunnel基础上进行传输,对应到上面的dialFunc过程就是:
可以看到http站点是不需要发CONNECT请求的,而是直接将目标站点的url作为path 填写在http请求头中。
为何上面的dialfunc访问http站点不行呢,查了squid代理的文档,发现squid默认会禁止非https站点通过CONNECT方法建立通道,自己搭了个squid代理去掉配置项,发现上面的dialfunc是可以访问http、https站点的,就是说http,https都先建立通过,再请求。
看了fasthttp的源码,没办法在请求前修改request header中的path为目标站点url,所以如果需要通过fasthttp使用http代理,那么可以使用上面的dialfunc,同时代理需要允许非443端口的站点可以建立通道。如果做不到这一点,那么还是建议使用标准库net/http的client,会更方便一点。