网络编程入门, 100行实现Websocket转TCP代理

本文发表于入职啦(公众号: ruzhila) 大家可以访问入职啦学习更多的编程实战。

🎉 用Go实现Websocket转TCP代理,浏览器可以访问TCP Socket,网络编程入门 实用项目 👏 🎉

项目地址

代码已经开源, websockify-go 👏 欢迎Star

代码运行效果:

Websockify

所有的项目都在github上开源:100-line-code 欢迎Star 👏

用100行代码的不同语言(Java、Python、Go、Javascript、Rust)实现项目,通过讲解项目的实现,帮助大家学习编程

会定期在群里分享最新的项目实战代码,包括不同语言的实现

老师还会详细讲解代码优化的思路,扫码加入实战群:
入群学习

为什么需要Websocket转TCP

Websocket是一种全双工通信协议,可以在浏览器和服务器之间建立持久连接,用于实时通信。但是Websocket只支持文本和二进制数据,无法直接访问TCP Socket。
如果要在网页上访问TCP Socket,就需要一个代理服务器,将Websocket请求转发到TCP Socket, 这就是Websocket转TCP代理:

Websocket <----> Websocket转TCP代理 <----> TCP Socket

典型的场景:

  • 在浏览器上访问VNC远程桌面
  • 在浏览器上访问SSH终端
  • 在浏览器上访问数据库管理工具
  • 在浏览器上访问自定义TCP服务, 比如游戏服务器或者IM服务器

novnc/websockify是一个非常流行的Websocket转TCP代理,但是它是用Python实现的,性能不够好,代码也很复杂

用Go实现一个Websocket转TCP代理,性能更好,更稳定

Go实现Websocket转TCP代理

Go特别适合网络编程,标准库提供了丰富的网络库,不仅性能好,而且代码简洁,只需要一个可执行文件就可以运行,不需要依赖其他库
这次要通过100行代码实现一个Websocket转TCP代理:

  • 要支持SSL
  • 要支持自定义URL路径
  • 要支持自定义目标地址
  • 完整的单元测试和标准的服务程序架构

代码

在这里插入图片描述

代码解析

代码结构

  • cmd/main.go 是程序的入口,解析命令行参数,启动服务
  • websockify.go 是Websocket转TCP代理的核心代码
  • websockify_test.go 是单元测试代码
  • Dockerfile 是构建Docker镜像的文件,方便部署可以直接上生产系统

启动一个HTTP服务器

在这里插入图片描述

  • 82行: 监听一个HTTP端口
  • 89-95行: 如果是443并且有SSL证书,就启动一个HTTPS服务器
  • 86行: 利用标准库创建一个能自定义处理的HTTP Server

处理Websocket请求

采用了gorilla/websocket库来处理Websocket请求,这个库是Go语言中最流行的Websocket库

所有的业务逻辑都在ServeHTTP函数:
在这里插入图片描述

  • 31行: 升级HTTP连接为Websocket连接, Websocket协议是基于GET这个HTTP请求升级为Websocket协议
  • 36行: 利用defer关键字,当链接断开的时候,关闭TCP连接,确保不会泄露资源
  • 44-59行: 读取Websocket数据,转发到TCP Socket
  • 60-73行: 读取TCP Socket数据,转发到Websocket
一个链接启动了两个协程

其实从ServerHTTP这个函数开始,系统库就为每个请求创建了一个协程,这个协程负责处理这个请求
在这个函数里面又启动了两个协程:

  • 一个负责读取Websocket数据
  • 一个负责读取TCP Socket数据

这样就实现了一个链接同时处理两个方向的数据流

  • 43和75行 创建了能接受err的channel,当处理数据从协程出现错误的时候,就会发送一个错误到这个channel,然后当前的主协程就会退出关闭链接

单元测试

golang的单元测试非常的方便,只需要在文件名后面加上_test.go,然后在函数名前面加上Test就可以了
在这里插入图片描述

单元测试的逻辑:

  • 2-28行 创建一个测试用的TCP服务器,写了一个Echo服务器,就是把接收到的数据原样返回
  • 31-41行 创建一个Websockify代理服务器
  • 43-63行 启动一个Websocket客户端测试链接是否能正常工作

标准的服务器程序架构

这个项目提供了Dockerfile,现在Docker是最主要的线上程序交付方式,强烈建议用Docker部署服务
基于flag这个库,来处理命令行参数,这是Go语言标准库提供的命令行参数解析库

程序能支持的命令行参数来控制服务的启动

总结

通过Websockify这个项目,学习了Go语言的网络编程,Websocket是一个非常重要的协议,可以用于实时通信,实现一个Websockify的转发代理,对于内部项目的开发非常有用

Docker也是非常重要的技术,我们提供了Dockerfile,可以直接部署到生产环境

过去的演示项目都没提供单元测试,这里提供了一个非常实用的单元测试流程,大家可以参考即便是复杂的流程也是可以通过单元测试来验证的

交流

构建一个100行代码项目的实战群,大家可以扫码加入,一起学习编程

入群学习

也可以访问入职啦学习更多的编程实战

所有的代码都在github上开源:100-line-code 欢迎Star 👏

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值