Android WebSocket(socket.io)遇到的坑

一、导包如下

    //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 _args = new ArrayList() {{
                    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 packet = new Packet(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打印日志。

写于此以记心绪。
.
纯纯干货兴味索然
感谢阅读收获归你
不妥之处敬请指教

Android WebSocket(socket.io)遇到的坑_第1张图片
加我微信 共同探讨

.
.
.
.
.
.
.

你可能感兴趣的:(Android WebSocket(socket.io)遇到的坑)