前言
首先 SocketRocket 0.6.0 是支持 ipv6的,不过是对域名的支持。 对 ip地址形式 是没有做处理的。后台在接收到请求时,如果没有检查到 [ ] ,则会认为你是 ipv4 或者 是域名,于是报错:
Error Domain=SRWebSocketErrorDomain Code=2132 "Received bad response code from server: 400." UserInfo={NSLocalizedDescription=Received bad response code from server: 400., HTTPResponseStatusCode=400}
Bug
经过抓包发现,socket发送的http请求形式是这样的: ws:xxxx::xxx:xxxx:xxxx:xxxx:8001/websocket/sd 由于 公司 使用的是ip地址,正常区分ipv6的 host 和 port ,是需要像[host]:port 这样来进行请求的。
解决方案
Socket内部发送的Http请求,构造底层 Request的地方:
CFHTTPMessageRef SRHTTPConnectMessageCreate(NSURLRequest *request,
NSString *securityKey,
uint8_t webSocketProtocolVersion,
NSArray<NSHTTPCookie *> *_Nullable cookies,
NSArray<NSString *> *_Nullable requestedProtocols)
核心: 改动 Request Head 中 Host 的配置
static NSString *_SRHTTPConnectMessageHost(NSURL *url)
{
NSString *host = url.host;
if ([host containsString:@":"]) {
// ipv6 ip 地址形式的兼容
host = [NSString stringWithFormat:@"[%@]",host];
}
if (url.port) {
host = [host stringByAppendingFormat:@":%@", url.port];
}
return host;
}
感谢
感谢大佬的 SocketRocket简单使用与源码解析,让我对的整个过程有了更深的了解。