最近给某用户做微信服务号自定义开发,需求很简单,主要功能是从用户已有的系统读取数据显示在服务号中。虽然是微信服务号和Go语言的开发初学者,但是感觉实现过程也应该非常简单,也就是从用户已有的外网数据库中读出数据,调用微信的API展示,相信一周之内可以很快搞定。没想到实际开发过程中还是遇到了一些坑,将填坑过程总结如下:
1、 用户要求自定义菜单的二级菜单有6项,一开始没当回事,后来看微信API文档发现只支持5项二级菜单。
这个好解决,和用户沟通把多余的二级菜单移到另一个主菜单下,但估计会给用户留下不专业的印象啦
2、 服务端API采用Go语言开发,用户旧系统的数据库用的是SQLServer2000,是的,SQLServer2000,你没看错,很古老的数据库。
1) Go语言没有支持SQLServer2000的官方库。
从github上找到一个通过Go调用C语言ODBC类库的包,go-odbc,https://github.com/weigj/go-odbc,
2) go-odbc在go install时报错,提示找不到gcc。
从网上下了个mingw-get,下载gcc,设置环境变量,搞定gcc
3) 根据go-odbc的示例写了段最简单的测试代码,连接SQL2000,读表的某个字段,输出字段的值,运行时居然报错。
问下度娘,已经有人发现是go-odbc的自带bug,修改odbc.go的代码,修改
func (stmt *Statement) free() {
C.SQLFreeHandle(C.SQL_HANDLE_STMT, stmt.handle)
}
为
func (stmt *Statement) free() {
if stmt.handle != nil {
C.SQLFreeHandle(C.SQL_HANDLE_STMT, stmt.handle)
stmt.handle = nil
}
运行,成功取到数据并输出。感谢发现这个bug的作者,:)
4) 开始代入业务,读取某个表的text字段时,运行报内存溢出,多次测试发现只要是取text字段就报错。
将查询语句select txt from tab 修改为
Select substring(txt,1,8000) from tab,再结合select datalength(txt) from tab,循环多次取出字段值拼接字符串搞定。
这种处理方式治标不治本,估计要想彻底解决还得翻odbc.go的代码,等有空再说。
5) 往表中插入数据,插入中文乱码。
初步估计是Go语言的字符串默认为utf-8编码,需要转换成GB2312编码。从网上找到字符集转换包mahonia,https://code.google.com/p/mahonia/(code.google.com被墙,需要翻墙)
encoder := mahonia.NewEncoder("gb2312")
svalue := encoder.ConvertString("中文测试")
3、 开发完毕,部署,由于是与旧系统部署在同一台主机上,80端口已被旧系统占用,旧系统的真实端口是8080,用iis重定向80端口
修改Go开发的服务端API端口为9999,主机上访问http://localhost:9999/weixin/正常。
4、 外网测试,在客户端访问http://www.ooxx.com:9999/weixin/,居然提示404,找不到网页。
排查半天,最后才发现原来是用户的主机有防火墙,把9999端口打开,访问正常
5、 测试微信调用服务端API,结果微信服务号接入的用户API端口只能为80,现在的端口是9999。
用nginx做代理。先把iis的端口改为81,nginx监听80端口
server {
listen 80;
server_name www.ooxx.com
#默认转向旧系统的iis
location /{
proxy_pass http://www.ooxx.com:81/;
}
#服务端的API
location ^~/weixin/ {
proxy_pass http://www.ooxx.com:9999/weixin/;
}
}
测试,http://www.ooxx.com,可以访问旧系统;http://www.ooxx.com/weixin,可以访问服务端的API
6、 继续测试服务端的展示页面,http://www.ooxx.com/weixin/show?id=111,怎么页面效果和http://www.ooxx.com:9999/weixin/show?id=111的效果有点不一样,少了一些样式。
排查发现,页面引用了css文件,目录层级与weixin目录同级,不改代码的情况下只好再用nginx代理一次css目录了。
location ^~/css/ {
proxy_pass http://www.ooxx.com:9999/css/;
}
OK,样式也正常了。
7、 继续测试服务端的展示页面,发现图片没有正常显示。
排查发现,内容数据是从数据库中直接读出来的,内容中的图片路径是<img src=”/oldsys/xxx.jpg”></img>,这样一来,通过微信服务端读出来后的路径是http://www.ooxx.com/oldsys/xxx.jpg,而图片能正常显示的路径应该是http://www.ooxx.com:8080/oldsys/xxx.jpg,好办,nginx再来代理一次:
location ^~/oldsys/ {
proxy_pass http://www.ooxx.com:8080/oldsys/;
}
测试,图片显示正常。看来nginx真是个好东东
8、 在手机上测试,图片好像只显示了一半,另一半被挡住了
看来得想办法让图片自适应手机屏幕。在网上找到这个:移动网站图片自适应解决方法(jquery解决方案)http://zhaojie.cc/256
9、 继续测试,发现服务端API无法访问https://api.weixin.qq.com
有了上面第4点的经验,联系用户方管理员设置防火墙策略,可以访问了
10、 到了第2天,发现服务端API又无法访问https://api.weixin.qq.com了
联系用户方管理员,原来防火墙策略是针对IP的,api.weixin.qq.com这个域名有多个IP,昨天的策略只做了一个IP,下午的时候api.weixin.qq.com解析的IP变了,当然就不能访问了。管理员坚持称不可能开放所有的IP,最多两个,只好在hosts中做了两个IP绑定api.weixin.qq.com
修改主机的C:\windows\system32\drivers\etc\hosts文件,增加下面两行
IP1 api.weixin.qq.com
IP2 api.weixin.qq.com
祈祷qq这两个IP千万不要挂。