解决Android云信突然不能发送图片,视频和语音异常问题 -- https惹的祸
Posted microhex
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决Android云信突然不能发送图片,视频和语音异常问题 -- https惹的祸相关的知识,希望对你有一定的参考价值。
去年写了一篇使用云信集成过程踩到的坑: 地址 集成上线之后,由于需要忙其他的项目,这个就扔给其他人了,直到最近有新的项目需要重新接入聊天组件,然后我们就aar集成了,过程什么的一切都很顺利,直到测试给了报出了异常:
突然发现不能发送图片,视频,还有语音,最后发现只要是文件类型的Message都不能发送!第一反应就是是不是集成本身存在问题,是不是云信的sdk出了问题,是不是我的主module中有什么设置导致云信不能正常进行???
由于时间非常紧,我给自己排期说最多三天可以解决问题,上面同意之后,我赶紧进行测试。首先说明一下云信上传文件的逻辑:首先像自家的服务器获取上传地址和上传token,然后使用上传token和文件一起上传!
首先我翻了线上正常的代码,打了个正式环境中的测试包,发送了一张图片,然后打印日志如下:
首先上传,然后返回值,再通过返回值response上传文件,这是正常的上传逻辑,最后也能上传数据,app数据中也有正确的回调,显示也正常。
然后我把目光转移有问题的新的APP上,打开日志,然后也得到了如下的日志:
但是它只显示 http post task is excuting
,最后就没有显示结果了。问题也到这里终结了,
这里发送消息三个接口都没有回调,页面也一直卡在这里。就像这样:
一直都是0%,没有显示上传失败,也没有成功!!!
一切弄得我很尴尬,没办法,那就看源码吧:
先找到sendMessage的实现类,目前来说是基于云信6.6.0的版本,代码混淆了,不过还能看:
然后找到com.netease.nimlib.q.f.a
,最后一路找下去(其中的艰辛不想说了,不是人干的活儿),找到了我们的目标类:
com.netease.nimlib.m.a.b.a
的
e
文件,其中c
方法为 :
private c b(String var1, byte[] var2)
com.netease.nimlib.k.b.b(o, "http post task is executing");
InputStream var3 = null;
short var4 = 799;
c var13;
try
this.a = com.netease.nimlib.m.a.c.b.a(var1, "POST");
com.netease.nimlib.m.a.c.b.a(this.a, "NIM-android-NOS-Upload-V6.6.0", com.netease.nimlib.m.a.b.a.c().a(), com.netease.nimlib.m.a.b.a.c().b(), com.netease.nimlib.f.g.c());
int var5 = var2.length;
HttpURLConnection var14 = this.a;
if ("POST".equals(var14.getRequestMethod()))
if (var5 <= 0)
var14.setChunkedStreamingMode(0);
else
var14.setFixedLengthStreamingMode(var5);
if ((var14 = this.a) != null && var14 instanceof HttpsURLConnection && !TextUtils.isEmpty(com.netease.nimlib.f.g.c()))
com.netease.nimlib.m.a.c.b.a(this.a, "Host", com.netease.nimlib.f.g.c());
com.netease.nimlib.m.a.c.b.a(this.a, "x-nos-token", this.f);
if (this.l != null)
if (!TextUtils.isEmpty(this.l.b()))
com.netease.nimlib.m.a.c.b.a(this.a, "Content-Type", this.l.b());
if (!TextUtils.isEmpty(this.l.a()))
com.netease.nimlib.m.a.c.b.a(this.a, "Content-MD5", this.l.a());
if (this.l.c() != null && this.l.c().size() > 0)
Map var15;
Iterator var17 = (var15 = this.l.c()).keySet().iterator();
while(var17.hasNext())
String var6 = (String)var17.next();
com.netease.nimlib.m.a.c.b.a(this.a, "x-nos-meta-" + var6, (String)var15.get(var6));
com.netease.nimlib.m.a.c.b.a(this.a, var2);
int var16 = this.a.getResponseCode();
if ((var3 = this.a.getInputStream()) != null)
var1 = com.netease.nimlib.m.a.c.b.a(var3);
if (var16 == 200)
com.netease.nimlib.k.b.b(o, "http post response is correct, response: " + var1);
else
com.netease.nimlib.k.b.b(o, "http post response is failed, status code: " + var16);
var13 = new c(var16, new JSONObject(var1), (Exception)null);
else
var13 = new c(899, (JSONObject)null, (Exception)null);
catch (SSLPeerUnverifiedException var10)
com.netease.nimlib.k.b.e(o, "http post exception, e=SSL_PEER_UNVERIFIED_EXCEPTION," + var10.getMessage());
var13 = new c(1099, new JSONObject(), var10);
catch (Exception var11)
com.netease.nimlib.k.b.d(o, "http post exception, status code=" + var4, var11);
var13 = new c(799, new JSONObject(), var11);
finally
com.netease.nimlib.m.a.c.b.b(var3);
this.a.disconnect();
this.a = null;
return var13;
其实大家也看到了,我们之所以这么能确定是这个方法,是因为这个打印了最后语句:
http post task is executing
中间是有一段拼接参数的,我们着重看这句话:
com.netease.nimlib.m.a.c.b.a(this.a, var2);
int var16 = this.a.getResponseCode();
if ((var3 = this.a.getInputStream()) != null)
var1 = com.netease.nimlib.m.a.c.b.a(var3);
if (var16 == 200)
com.netease.nimlib.k.b.b(o, "http post response is correct, response: " + var1);
else
com.netease.nimlib.k.b.b(o, "http post response is failed, status code: " + var16);
var13 = new c(var16, new JSONObject(var1), (Exception)null);
既然我们找到这里的输出,那我们就打个debug吧,一打就打出了问题了:
问题是这样的:
首先在488行的时候,a应该是HttpURLConnection
,但是到了下面我们发现它变成了OkHttpsURLConnection
,云信是没有用到OKHttp
的啊,OKHttp
只是我的项目中用到的啊,我的项目中的OkHttp
怎么会影响到云信这个module中的内部请求呢?那么这个HttpURLConnection
怎么转变为OkHttpsURLConnection
的呢?
那我们来看看这个方法:
深入发现
public static HttpURLConnection a(String var0, String var1) throws IOException
HttpURLConnection var2;
(var2 = (HttpURLConnection)(new URL(var0)).openConnection()).setRequestMethod(var1);
return var2;
此时发现的HttpURLConnection
已经变成了OkHttpsURLConnection
,那么这个OkHttpsURLConnection
是哪里来的呢?
经过查找和分析,这是当年加的一个测试工具,用来检测网络请求的,具体的逻辑是代理了网络请求,在中间网络请求OkHttp中又加了一个Interceptor
,不过没想到的是这个Interceptor
代理了全部网络请求,包括https,那么此时我的Interceptor
就相当于中间人,所以发起的https的请求都将无效。
然后,去掉这个工具,再次测试,一切OK!图片、视频和语音可以正常发送!!!
对了,这个网络测试工具为:
api "com.github.whataa:pandora:v2.0.4"
github地址为:https://github.com/whataa/pandora 除了网络测试,它还可以用来检测UI界面:
大家可以尝试一下:)
总结一下:
这次主要是https惹的祸,花了我好几天的世界才确定问题所在,分析几次代码都没搞定,最后一次偶然情况下才发现了是我的这个代理问题。
最后,如果你发现你的https请求也出现过这种问题,不妨先查查自己的网络是否联通,是否被代理。如果有,修复一下再试试!
以上是关于解决Android云信突然不能发送图片,视频和语音异常问题 -- https惹的祸的主要内容,如果未能解决你的问题,请参考以下文章