每天学习一点点,成功增加一大步

Android 即时通讯工具 socket.io

Android zhanghui 1776℃

前段时间一直在忙写一个 Android 的在线客服的项目,这个在之前的博文的记录中有提到过,虽然这个项目的编写已经完成,但到现在还没有把这个实践的过程给记录下来,所以今天将这个过程给补上。

对于什么是 socket.io 及其的作用网络上也大量的信息可以搜索得到,在这篇中文中就不多写了。使用 socket.io 的好处是可以不依赖第三方的信息推送服务(如小米、华为等都有提供这样的服务),建立起自己的信息推送平台。

回归文中正题记录一下在 Android 项目中如何使用 socket.io 来与 socket.io 的服务器进行通信,而 socket.io 服务端的搭建过程不是本文的重点,而且同样的网络也有这样的信息(包括了不同后台语言的版本,如JAVA、NodeJs、PHP等),本文的重点是记录如何在 Android 项目中使用 socket.io 与服务端保持通信。当时为了实现这个需求花费了大量的时间,走了不少的弯路。

需求的实现首先要找到依赖的包,坦白的说网络对于 Android 的 socket.io 有不同的版本,这就让初次接触的人吃了亏,而且很多的复制的信息,所以只能是已经收集了

android io.socket.client.zip

添加依赖库到项目

在下载压缩包后,释放到项目的 app/libs 目录下,再通过 Android Studio 将里面的所有 jar 都引入到项目中。

在项目的自建 socket 类中引入

import io.socket.client.Ack;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

初始化 Socket

public class AppSocket {

    static String TAG = AppSocket.class.getName();
    public static boolean isRunning = false;

    static Socket mSocket;
    Context ctx;

    public AppSocket() {
        ctx = MyApplication.getContext();
    }

    public void init() {
        Properties properties = Common.getProperties(ctx);
        String url = properties.getProperty("socketHost") + ":" + properties.getProperty("socketPort");
        int timeOut = Integer.parseInt(properties.getProperty("socketTimeOut"));
        MyLog.i(TAG, "conn:" + url);
        IO.Options options = new IO.Options();
        options.transports = new String[]{"websocket"};
        //失败重试次数
        options.reconnectionAttempts = 1;
        //失败重连的时间间隔
        options.reconnectionDelay = 1000;
        //连接超时时间(ms)
        options.timeout = timeOut;
        try {
            mSocket = IO.socket(url);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

}

监听服务器推送过来的事件及传参

connect 方法:接收服务器发来的事件之前,首先就要打通与服务器的通信道路,就像要与对方通电话,首先要拨通对方的电话是一个理。

on 方法:监听服务器端发送过来的事件,然后通过回调来收到对方发来的具体数据,当前对方也可以不发无关的信息。

private void conn() {
    MyLog.i(TAG, "conn");
    mSocket.connect()
            .on(Socket.EVENT_CONNECTING, listener_connectIng)
            .on(Socket.EVENT_CONNECT_TIMEOUT, listener_connectTimeOut)
            .on(Socket.EVENT_CONNECT_ERROR, listener_connectError)
            .on(Socket.EVENT_CONNECT, listener_connect)
            .on("[event]", new Emitter.Listener() {
                @Override
                public void call(Object... objects) {
                    MyLog.i(TAG, "接收到事件后的回调");
                    // objects 就是传回的JSON数据、string数据或为null
                }
            });
}

private Emitter.Listener listener_connectIng = new Emitter.Listener() {
    @Override
    public void call(Object... objects) {
        MyLog.i(TAG, "连接中");
    }
};

private Emitter.Listener listener_connectTimeOut = new Emitter.Listener() {
    @Override
    public void call(Object... objects) {
        MyLog.i(TAG, "连接超时");
    }
};

private Emitter.Listener listener_connectError = new Emitter.Listener() {
    @Override
    public void call(Object... objects) {
        MyLog.i(TAG, "连接失败");
    }
};

private Emitter.Listener listener_connect = new Emitter.Listener() {
    @Override
    public void call(Object... objects) {
        MyLog.i(TAG, "on 连接成功");
    }
};

向服务器方发送事件和传数

除了要监听服务器传过来的信息,还是要给服务器方发送信息吧,至少告诉服务器这边已经接收到时你发送过来的信息吧,这就是有来有往吧,不可能有来无往,那人家会失望,也就没有交往的意义了。

比如当连接成功后,得要给对方标明自己的身份是谁吧。

private Emitter.Listener listener_connect = new Emitter.Listener() {
        @Override
        public void call(Object... objects) {
            MyLog.i(TAG, "on 连接成功");
            try {
                // 我是訂閲對象
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("uid", apiMsgByService.getUserCode());
                jsonObject.put("token", apiMsgByService.getToken());
                mSocket.emit("Init", jsonObject, new Ack() {
                    @Override
                    public void call(Object... args) {
                        MyLog.i(TAG, "emit");
                        MyLog.i(TAG, "服务端返回结果:" + args[0]);
                    }
                });
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    };

Init 就是客户端发给服务端的事件,表明自己的身份,让服务器知道已经通信成立成功,让服务端初始化下自己的在线信息。

断开与服务器的连接

有互相的连接、来往的传送信息,总有疲惫的时候吧想要下线,这个时候不能老占用这条通信道路吧,这样其他人要用的时候怎么办,所以要让路予他人吧。

public void destroy() {
    MyLog.i(TAG, "释放连接");
    mSocket.off();
    mSocket.disconnect();
    isRunning = false;
}

转载请注明:隨習筆記 » Android 即时通讯工具 socket.io

喜欢 (16)