本文源自: http://blog.justbilt.com/2016/06/19/quickx-ipv6/?utm_source=tuicool&utm_medium=referral
quick-x 适配 IPV6
一. IPV6 是啥 ?
这两天一个运营的同事跑过来问我:
他: 咱们的游戏适配那啥 VIP6 了么?
我: ….
苹果商店在儿童节之后就不允许未适配 IPV6 的应用上架了, IPV6 是啥 ? 需要做些什么呢 ? 看完这两篇文章就明白了:
iOS应用支持IPV6,就那点事儿
针对苹果最新审核要求为应用兼容IPv6
虽然这两篇文章是针对应用的, 但是从中我们也能了解大概的做法:
- 不建议使用底层的网络API
- 不要用IP地址
二. COCOS2D-X 适配 IPV6
cocos 依赖的三方库涉及到 IPV6 问题的库为 curl
, websocket
, cocos 自己提供的模块需要适配的有:
- HttpClient
- AssetsManagerEx
- SocketIO
- WebSocket
- Console
- ScriptingCore
cocos 官方也第一时间适配了 IPV6, 具体内容可以看这篇文章:儿童节后苹果爸爸只爱IPv6 Cocos2d-x第一时间支持, 里面描述的很简单:
如果你需要支持纯IPv6网络,只需要更新CURL和libwebsocket网络。
让我们尝试一下.
1. 下载 cocos2d-x-3rd-party-libs-bin
这一步看似很简单, 实则不然. 你不会想到从 github 上下载一个 100 多 MB 的文件是多麽困难, 为此我花费了近 2个小时的时间.
我下载的是 99 版的, 解压代用.
2. 更新 curl
拷贝解压出来的文件夹中的 curl
目录到 quick-cocos2d-x/external
, 替换原来的 curl
目录.
打开 xcode, 编译, 发现有 100 多个错误:
![image_1alkfke1vag91ccc1p15179c1jtcm.png-113.9kB](https://i-blog.csdnimg.cn/blog_migrate/ac7ced6ea4a6e23957ee02972c25cf64.png)
1 | Undefined symbols for architecture i386: "_ASN1_INTEGER_get", referenced from: _ossl_connect_common in libcocos2d iOS.a(libcurl_la-openssl.o) "_ASN1_STRING_data", referenced from: _ossl_connect_common in libcocos2d iOS.a(libcurl_la-openssl.o) "_ASN1_STRING_length", referenced from: _ossl_connect_common in libcocos2d iOS.a(libcurl_la-openssl.o) ... |
不要惊慌, 这是因为新版本 curl 多了一些静态库, 我们需要引入它们, 在 XCode 项目输找到 cocos2d_lib > external > curl > ios
目录上右键, 选择 Add Files to 'cocos2d_lib.xcodeproj'
:
![image_1alkfv73t446cr3sc41r6r1hqj13.png-238.8kB](https://i-blog.csdnimg.cn/blog_migrate/0c6d591277e2e931b2e026ea0ff93d11.png)
选中 libcrypto.a
和 libssl.a
, targets 选择 libcocos2d iOS
, 确定, 重新编译, 搞定.
3. 更新 websocket
注: 我们项目并没有用到 websocket , 所以这里只是搞到编译通过, 运行时有木有问题就不到知道了!
和 curl 类似, 拷贝 cocos2d-x-3rd-party-libs 中的 websockets
目录到 quick-cocos2d-x/external
, 替换原来的 websockets
目录.
因为最新版的 websockets api 变化挺大, 所以我们需要使用 cocos 最新的 WebSocket.h 和 WebSocket.cpp 替换 quick-cocos2d-x/cocos/network 中的 WebSocket
.
编译, 会有一处错误发生在 WebSocket::WebSocket()
中, 因为 quick 中并没有 Director::EVENT_RESET
消息, 我们注释掉这段代码即可.
1 | { |
三. QUICK-COCOS2D-X 适配 IPV6
1. 如何适配
quick-x 中主要是 luasocket 的适配, 适配的方法就是选择性的调用 socket.tcp6()
和 socket.tcp()
, udp 也是如此.
quick-x 中调创建 socket 是在 SocketTCP:connect
函数中, 并没有预留 ipv6 参数, 我们需要添加一下:
1 | function SocketTCP:connect(__host, __port, __retryConnectWhenFailure, __ipv6) |
然后, 如果要连接 ipv6 的服务器的话, __ipv6
值传 true
即可.
2. 如何判断一个服务器是 ipv6 还是 ipv4
lua 中 socket 的 dns 模块提供了一个函数 getaddrinfo
, 可以返回一个服务器的 dns 解析结果数组, 其中一个很重要的字段就是 family
, 有 inet
和 inet6
两个值可选.
大家可以运行 dump(socket.dns.getaddrinfo("ipv6-test.com"))
看下结果:
1 | - "<var>" = { |
我们遍历一下这个结果, 如果其中有 "family" = "inet6"
的解析, 就可以使用 ipv6 进行连接了, 代码实现如下:
1 | local function isSupportIpv6(_domain) |
我们将这个函数的结果作为 SocketTCP:connect
的最后一个参数传入即可.
四. 还有什么要注意的
1. 一定要使用使用域名
向苹果提审的服务器一定要使用域名, 所有的地方都是如此, 包括 http 请求, 热更新返回的 version.md
地址.
2. 做好兼容性测试
测试 IPV6 ONLY 的时候使用最新的 iOS 9.3 做测试, 苹果他们审核的时候也是只审核最新的系统是否正常.
但是我们实现的时候要兼容的不同的系统, 网络环境(IPV6 兼容
和 IPV6 ONLY
), 因为用户的网络可能是各种各样样, 这些组合都要测试到.