引言

最近需要对接一个接口,人家提供了两种调用方式,第一种是基于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开发一个本地代理相关推荐

  1. java linux 管理系统_用Java开发一个本地服务管理软件

    使用Java开发一个本机服务管理程序,能够控制本机Tomcat.Apache服务的开启和关闭,图形界面控制.用户可以自己扩展其他服务,用来学习图形界面编程.多线程.事件响应等都不错. 一.最终界面 先 ...

  2. vscode中为golang开发环境配置代理goproxy

    和 npm . pip 等包管理工具一样,你的包都是从网上拉去到本地,然而,由于国内网络的原因,这些工具 你都得换国内代理,要不然下载很慢或直接失败. 这篇文章所讲的 为golang开发下载插件(开发 ...

  3. 快速用golang开发一个上传excel入库到sqlserver的应用

    这个小的功能本来想用php开发的,但用php开发的话,需要安装php的mssql sqlserver的扩展,并且还要安装nginx +php-pfm +php的服务,很麻烦,但如果用golang开发的 ...

  4. vue-webpack项目本地开发环境设置代理解决跨域问题

    vue-webpack项目本地开发环境设置代理解决跨域问题 参考文章: (1)vue-webpack项目本地开发环境设置代理解决跨域问题 (2)https://www.cnblogs.com/xyyt ...

  5. 以前给客户开发了一个本地同城小程序

    以前给客户开发了一个本地同城小程序,今天客户联系我,想在小程序上加外卖功能,然后我告诉客户,以前开发这个小程序没多少钱,功能相对来说也不复杂,如果现在要加外卖功能的话就完全不一样了,开发外卖功能的开发 ...

  6. 一个快速使用 Golang 开发和构建生成 NodeJS Addon 扩展的开发工具

    GonaCli 一套快速使用 Golang 开发和构建生成 NodeJS Addon 扩展的开发工具 GONACLI 是一个快速使用 Golang 开发 NodeJS Addon 扩展的开发工具,开发 ...

  7. golang开发环境配置以及简单使用

    golang开发环境配置以及简单使用 编译golang程序 go build命令的使用 http://c.biancheng.net/view/120.html 使用go build, 将main.g ...

  8. 使用 NSURLSession 开发一个支持后台下载和断点续传的下载工具

    NSURLSession 是 iOS 系统提供给我们的原生网络操作库,它提供了网络操作相关的一系列特性支持,比如缓存控制,Cookie管理,HTTP 认证处理等等,是一套整体的网络操作处理解决方案. ...

  9. Linux下golang开发环境搭建

    对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...

最新文章

  1. 软件测试培训分享:软件测试初期怎么面试工作?
  2. 【activeMQ】一、入门
  3. 如何在centos7上网卡名称回归传统
  4. Leetcode 94. 二叉树的中序遍历 解题思路及C++实现
  5. 【C语言】数据结构C语言版 实验2 不带头结点的单链表
  6. python中实现多线程的几种方式
  7. oracle:实现滑动平均效果
  8. python中文字体奇怪_利用python检查 AS400的中文字问题
  9. 如何在 Mac 上的“终端”中执行命令和运行工具?
  10. 接口测试工具之抓包工具介绍
  11. 基于单片机的简单温控风扇
  12. ALSA架构应用程序aplay及amixer调用关系(应用层到内核驱动)
  13. 编写一个简单加密程序!!!
  14. 分布式任务调度平台201902
  15. 【USB笔记】设备功能描述符Device Capability Descriptor
  16. 新浪微博首席PHP技术顾问惠新宸:相信PHP可以走的更长远
  17. java对接七牛后台进行内容审核(鉴黄、敏感人物、暴恐)
  18. mysql中$和_在数据库中,$和#代表什么意思?
  19. iOS 九宫格抽奖(弱鸡)
  20. 文件比较 java 标红_如何用java输出word里红色的字体,

热门文章

  1. 不懂怎么识别图片中的文字?在线教你识别文字方法
  2. 使用PaddleOCR识别文字 (一) 安装过程问题及解决
  3. 贵州大数据:“云上贵州”昨天正式开通
  4. 纯css实现超炫酷的星空背景按钮
  5. linux网卡流量限速wondershaper
  6. java酒店入住管理系统代码_基于jsp的酒店入住管理系统-JavaEE实现酒店入住管理系统 - java项目源码...
  7. 2021,从多云到专有云?
  8. 微信扫码支付初步使用
  9. 线性度不太好的原因分析
  10. 计算机摄像头找不到怎么办,我的电脑怎么没有摄像头