一、导包如下
//compile 'com.github.nkzawa:socket.io-client:0.3.0'//已过时,仅用于聊天Socket连接(js变种版websocket)
compile ('io.socket:socket.io-client:0.8.3') {//最新包
exclude group: 'org.json', module: 'json' //处理: WARNING: Dependency org.json:json:20090211 is ignored
}
PS:配置参考地址:https://socket.io/blog/native-socket-io-and-android/
二、发送消息
/**
* Emits an event. When you pass {@link Ack} at the last argument, then the acknowledge is done.
*
* @param event an event name.
* @param args data to send.
* @return a reference to this object.
*/
public Emitter emit(final String event, final Object... args){
...
}
上面的方法一些正常,下面还以一个带Ack监听
/**
* Emits an event with an acknowledge.
*
* @param event an event name
* @param args data to send.
* @param ack the acknowledgement to be called
* @return a reference to this object.
*/
public Emitter emit(final String event, final Object[] args, final Ack ack) {
...
}
在demo是一切正常,连接正常,登录正常,登录有回调的。但是正式的出问题了。
//Socket绑定监听
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
//mSocket.io().on(Manager.EVENT_TRANSPORT, trans);//网上说SSL出问题,但是问题没有得到处理
mSocket.on(EVENT_MSG, msg);
mSocket.connect();
1、流程:
①、在onConnect连接成功,②、emit(event, objects[], ack)发送登录信息msg
2、问题:
发送的登录信息msg用户名是英文没有任何问题,奇葩来了,如果含有中文则调onDisconnect监听断开连接,打印args[0].toString():transport error。
关键的是接口同事打印,收到并解析 登录信息 成功,也给回包了。
3、处理bug:
首先想到的包的问题是否过时,替换最新的依然是:外甥打灯笼---照舅。
然后就开始百度生涯:android io.socket disconnect transport error
不负有心人,找到如下几个当时认为可用的,确实也收到启发。
https://stackoverflow.com/questions/29073746/socket-io-disconnect-event-transport-close-client-namespace-disconnect
https://stackoverflow.com/questions/37093221/using-socket-io-on-android-always-returns-xhr-poll-error
官网:https://socket.io/docs/client-api/
但问题没有解决,已经到快到十点了,还是明天处理。换一个思路打断点监听onDisconnect,找出的问题发生的时间点。
打断点查看一步步的流程:
又发生了奇葩的问题,打断点时候有时能收到登录成功的回调,有时收不到。查找源码
/**
* Emits an event with an acknowledge.
*
* @param event an event name
* @param args data to send.
* @param ack the acknowledgement to be called
* @return a reference to this object.
*/
public Emitter emit(final String event, final Object[] args, final Ack ack) {
EventThread.exec(new Runnable() {
@Override
public void run() {
List<Object> _args = new ArrayList<Object>() {{
add(event);
if (args != null) {
addAll(Arrays.asList(args));
}
}};
JSONArray jsonArgs = new JSONArray();
for (Object _arg : _args) {
jsonArgs.put(_arg);
}
int parserType = HasBinary.hasBinary(jsonArgs) ? Parser.BINARY_EVENT : Parser.EVENT;
Packet<JSONArray> packet = new Packet<JSONArray>(parserType, jsonArgs);
logger.fine(String.format("emitting packet with ack id %d", ids));
Socket.this.acks.put(ids, ack);
packet.id = ids++;
Socket.this.packet(packet);
}
});
return this;
}
有时走到add(event);有时走到addAll(Arrays.asList(args));断开连接onDisconnect,又一次偶尔停顿了一下,Ack 有反应,收到的回包。预感问题找到了。又跑一次,debug慢点,Ack 收到登录回包;再次验证,Ack 都有回包。狂喜,问题找到了,哈哈哈!!!
这属于线程间的异步通信问题,(PS:volatile原子性问题,32位的不会出现,但是64位的就会出现。这就解释了字母正常,汉字不正常)
处理方法如下:
new Thread(){
@Override
public void run() {
try {
Thread.sleep(400);//延迟发送
} catch (InterruptedException e) {
e.printStackTrace();
}
mSocket.emit(EVENT, new Object[]{loginMsg()}, ack);
}
}.start();
PS:正如前面所说有两种发送消息的方法,带Ack监听要特殊处理一下。
public Emitter emit(final String event, final Object... args)
public Emitter emit(final String event, final Object[] args, final Ack ack)
总结
debug断点调试要勤用,还有log打印日志。
加我微信 共同探讨写于此以记心绪。
.
纯纯干货兴味索然
感谢阅读收获归你
不妥之处敬请指教
.
.
.
.
.
.
.
网友评论