使用Golang开发一个本地代理
引言
最近需要对接一个接口,人家提供了两种调用方式,第一种是基于IE浏览器的Active,第二种是动态链接库dll。我们公司的产品不支持IE,所以只能通过调用dll来完成了。
之前我已经用Java实现了这个代理,但是感觉很笨重,依赖于容器还有JVM一大堆,这个代理要安装在客户端电脑上,基于Http协议来调用,然后透传参数调用dll,将返回的结果转换为Json。
如今我想用Golang来实现这个功能,它不依赖特定的运行环境,而且天然高并发,适合做网络通信相关,结合了Java的高效和C的高性能。
一、功能拆解
- http模块
- 调用dll
- 返回结果处理
功能大致上分为三步,三步独立完成,分步进行。第一个很简单,网上一搜就出来了,也没遇到什么波折。然后直接测试调用dll,这个耽误了不少时间,不知道问题出在哪,又不好测试,打的包不在dll所在文件夹里,每次还要复制过去测试。
二、遇到的问题
1. 对于入参和出参的处理
void _stdcall PostAndRecvEx(IN char* pszPost, OUT char* pszRecv)
参数:pszPost 输入XML信息pszRecv 返回XML信息
返回值:无
2. 程序异常退出
由于dll文件在指定的安装目录,将golang生成的exe复制过去后才能找到它,但是一运行却出现闪退,根本不知道哪里出了问题。
3. 中文乱码
这里体现在两个地方,一是输入参数无法被dll中的函数识别,一直报错。第二个是输出的xml中包含中文乱码。
4. 返回结果无法映射到结构体
要转成Json,首先应该定义结构体,我是利用返回结果直接测试的,但是返回的xml无法映射到结构体对应的字段上,怀疑是编码问题,返回的xml指定了GBK(encoding="gbk")。由于是模拟的返回数据,我直接修改了编码发现可以映射到指定字段。网上查了下没什么好办法,看到这个很妙就直接用了:
xmlDataRsp = strings.Replace(xmlDataRsp, "gbk", "UTF-8", -1)
三、涉及知识点
1. 如何使用http模块写一个服务(找个官方的示例)
import ("fmt""log""net/http"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}func main() {http.HandleFunc("/", handler)log.Fatal(http.ListenAndServe(":8080", nil))
}
2. 如何调用dll(这个也有几种方式)
dll := syscall.NewLazyDLL("NISEC_SKSC.dll")
proc := dll.NewProc("PostAndRecvEx")
3. 捕获异常 明确问题点
defer func() {//恢复程序的控制权err := recover()if err != nil {fmt.Println(err)}
}()
// 可能出问题的代码
4. 如何使用cgo
//#include <stdio.h>
//#include <stdlib.h>
import "C"
import ("bytes""strconv""unsafe"
)func main() {cs := C.CString("你好")defer C.free(unsafe.Pointer(cs))println(cs)
}
一开始以为注释是没用的,后来才知道编译器识别加注释的c代码(通过import "C")
5. 底层数据类型不一致的处理
使用java调用dll的时候我特地在后面加了结束符:
JNAOperateDll.instanceDll.PostAndRecvEx((xmlStr + "\0") .getBytes("gbk"), b);
用golang的时候,我也一直不知道如何处理,到底该用字符串加"\0",还是字节加\x00。
这就要了解golang和c对字符的处理,c需要通过结束符来判断字符串何时结束,而golang不需要,它有长度标识。
6. xml转json
golang要转json,需要定义结构体来搭桥,所有属性都要有对应的字段。网上找到一个不需要结构体的,但是star数量不多,而且没下载下来。
四、总结
1. 做事情要知道事情的边界
像我们这个需求,要和其他接口交互,而且不是基于http协议,我们公司的产品放弃了IE的支持,所以只能通过调用dll来实现。这就是边界,无法突破的壁垒。
2. 在边界内力求做到最好
知道了事情的边界,力求在边界内做到最好。起初我就觉得用Java来实现不太好,但是客户催得紧,还要调试这些接口,就迅速用Java实现了。后来回过头我就想着如何优化它,如何一键启动甚至开机自启,如何设置成windows服务,但是这都改变不了它庞大且不利于传播的事实,后来想起来golang,这玩意真是天生做这个的料。
3. 遇到问题不要轻易放弃
在写这个代理的过程中,遇到了较多困难,毕竟是不熟悉的语言,虽然它的功能看起来很简单,但是我一开始还是有点虚,例如看到了指针,我就怕遇到了这些环环相扣的陷进去了,不过我还是鼓励自己不断去尝试,边做边学。
4. 形成自己做事的方法
在做这个工具的时候,我是分几步进行的,大方向上没有变,最后把代码合起来,就是一个完整的功能。我觉得这样拆分可以各个击破,专注于一个个点,而且可以将难度分化,给人以信心。
这次我也没有一开始就去看golang的语法,学习那些东西,我是直接开干,需要什么我就去查什么。当你学会一种开发语言后,需要借助于另一个语言完成某个功能,这种方法我觉得很好,不会陷入另一个语言的大坑,针对目标在实践中学习,高效而深刻。
转载于:https://www.cnblogs.com/lucare/p/10587315.html
使用Golang开发一个本地代理相关推荐
- java linux 管理系统_用Java开发一个本地服务管理软件
使用Java开发一个本机服务管理程序,能够控制本机Tomcat.Apache服务的开启和关闭,图形界面控制.用户可以自己扩展其他服务,用来学习图形界面编程.多线程.事件响应等都不错. 一.最终界面 先 ...
- vscode中为golang开发环境配置代理goproxy
和 npm . pip 等包管理工具一样,你的包都是从网上拉去到本地,然而,由于国内网络的原因,这些工具 你都得换国内代理,要不然下载很慢或直接失败. 这篇文章所讲的 为golang开发下载插件(开发 ...
- 快速用golang开发一个上传excel入库到sqlserver的应用
这个小的功能本来想用php开发的,但用php开发的话,需要安装php的mssql sqlserver的扩展,并且还要安装nginx +php-pfm +php的服务,很麻烦,但如果用golang开发的 ...
- vue-webpack项目本地开发环境设置代理解决跨域问题
vue-webpack项目本地开发环境设置代理解决跨域问题 参考文章: (1)vue-webpack项目本地开发环境设置代理解决跨域问题 (2)https://www.cnblogs.com/xyyt ...
- 以前给客户开发了一个本地同城小程序
以前给客户开发了一个本地同城小程序,今天客户联系我,想在小程序上加外卖功能,然后我告诉客户,以前开发这个小程序没多少钱,功能相对来说也不复杂,如果现在要加外卖功能的话就完全不一样了,开发外卖功能的开发 ...
- 一个快速使用 Golang 开发和构建生成 NodeJS Addon 扩展的开发工具
GonaCli 一套快速使用 Golang 开发和构建生成 NodeJS Addon 扩展的开发工具 GONACLI 是一个快速使用 Golang 开发 NodeJS Addon 扩展的开发工具,开发 ...
- golang开发环境配置以及简单使用
golang开发环境配置以及简单使用 编译golang程序 go build命令的使用 http://c.biancheng.net/view/120.html 使用go build, 将main.g ...
- 使用 NSURLSession 开发一个支持后台下载和断点续传的下载工具
NSURLSession 是 iOS 系统提供给我们的原生网络操作库,它提供了网络操作相关的一系列特性支持,比如缓存控制,Cookie管理,HTTP 认证处理等等,是一套整体的网络操作处理解决方案. ...
- Linux下golang开发环境搭建
对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...
最新文章
- 软件测试培训分享:软件测试初期怎么面试工作?
- 【activeMQ】一、入门
- 如何在centos7上网卡名称回归传统
- Leetcode 94. 二叉树的中序遍历 解题思路及C++实现
- 【C语言】数据结构C语言版 实验2 不带头结点的单链表
- python中实现多线程的几种方式
- oracle:实现滑动平均效果
- python中文字体奇怪_利用python检查 AS400的中文字问题
- 如何在 Mac 上的“终端”中执行命令和运行工具?
- 接口测试工具之抓包工具介绍
- 基于单片机的简单温控风扇
- ALSA架构应用程序aplay及amixer调用关系(应用层到内核驱动)
- 编写一个简单加密程序!!!
- 分布式任务调度平台201902
- 【USB笔记】设备功能描述符Device Capability Descriptor
- 新浪微博首席PHP技术顾问惠新宸:相信PHP可以走的更长远
- java对接七牛后台进行内容审核(鉴黄、敏感人物、暴恐)
- mysql中$和_在数据库中,$和#代表什么意思?
- iOS 九宫格抽奖(弱鸡)
- 文件比较 java 标红_如何用java输出word里红色的字体,