Android模拟服务端下发消息的Socket通讯工具

Android模拟服务端下发消息的Socket通讯工具

1. 背景简介

背景简介:
有些场景需要依赖服务端下发消息到客户端,比如PowerMsg,服务端下发消息Type,客户端解析Type做出相应动作。比如直播答题,需要依赖服务端下发消息,客户端拿到消息根据规则去展示题目等等。

2. 痛点说明

依赖服务端消息下发,客户端很被动,无法主动构造相应消息。所以急需一个可以模拟服务端消息下发的工具,socket工具由此而来。

3. 工具原理

电脑模拟Socket服务端,Android应用模拟Socket客户端,通过socket工具发消息到客户端。

4. Socket客户端代码

if (ConfigHelper.getInstance().getAppConfig().isDebug()
            && PreferenceCommon.getInstance().getBoolean("is_xx_socket_enable", false)) {
            Socket2PowerMsgTool.getInstance().setLiveMessageParserCallBack(this)
            Socket2PowerMsgTool.getInstance().startSocket()
        }

Socket2PowerMsgTool.java

public class Socket2PowerMsgTool {

    private static final String SocketIP = "30.5.195.154";
    private static final int SocketPort = 7654;

    Socket socket = null;
    private String recv_buff = null;

    private static Socket2PowerMsgTool instance = new Socket2PowerMsgTool();

    private Socket2PowerMsgTool(){
    }

    public static Socket2PowerMsgTool getInstance(){
        return instance;
    }

    private ILiveMessageParserCallBack mLiveMessageParserCallBack;

    public void setLiveMessageParserCallBack(ILiveMessageParserCallBack mLiveMessageParserCallBack) {
        this.mLiveMessageParserCallBack = mLiveMessageParserCallBack;
    }

    public void startSocket() {
        String ip = PreferenceCommon.getInstance().getString("live_mock_socket_ip", "");
        String portString = PreferenceCommon.getInstance().getString("live_mock_socket_port", "");
        if (TextUtils.isEmpty(ip) || TextUtils.isEmpty(portString)) {
            return;
        }
        int port = Integer.parseInt(portString);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //连接到指定的IP和端口号,并指定10s的超时时间
                    socket = new Socket();
                    socket.connect(new InetSocketAddress(ip, port), 10000);
                    if (socket != null && socket.isConnected()) {
                        while(true) {
                            recv();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void recv() {
        InputStream inputStream = null;
        try {
            inputStream = socket.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (inputStream != null){
            try {
                byte[] buffer = new byte[1024];
                int count = inputStream.read(buffer);//count是传输的字节数
                recv_buff = new String(buffer);//socket通信传输的是byte类型,需要转为String类型
                recv_buff = recv_buff.substring(0, count);
                String regex="^[A-Fa-f0-9]+$";
                if (recv_buff.matches(regex)) {
                    recv_buff = hexStringToString(recv_buff);
                }
                Log.i("ruihan-test", recv_buff);
                if (!TextUtils.isEmpty(recv_buff) && isJSONString(recv_buff)) {
                    MockPowerMsgEntity mockPowerMsgEntity = FastJsonUtil.json2pojo(recv_buff, MockPowerMsgEntity.class);
                    if(mockPowerMsgEntity != null) {
                        if (mockPowerMsgEntity.type == 1) {
                            if (mLiveMessageParserCallBack != null) {
                                mLiveMessageParserCallBack
                                        .msgLiveOriginalJsonPaserCallBack(FastJsonUtil.pojo2json(mockPowerMsgEntity.data));
                            }
                        } else if (mockPowerMsgEntity.type == 2) {
                            if (mLiveMessageParserCallBack != null) {
                                mLiveMessageParserCallBack
                                        .msgLikeParserCallback(JSONObject.toJavaObject(mockPowerMsgEntity.data, MsgLike.class));
                            }
                        } else if (mockPowerMsgEntity.type == 3) {
                            if (mLiveMessageParserCallBack != null) {
                                mLiveMessageParserCallBack
                                        .msgLiveStatusParserCallback(FastJsonUtil.pojo2json(mockPowerMsgEntity.data),
                                                JSONObject.toJavaObject(mockPowerMsgEntity.data, MsgLiveStatus.class));
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    public boolean isJSONString(String str) {
        boolean result = false;
        try {
            Object obj = JSONObject.parse(str);
            result = true;
        } catch (Exception e) {
            result = false;
        }
        return result;
    }

    public void closeSocket() {
        try {
            if (socket!= null) {
                socket.close();
                socket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接口回调实现:

override fun msgLiveOriginalJsonPaserCallBack(jsonString: String?) {
        val isBenefitType = LiveRoomUtils.isBenefitCoupon(jsonString)
        if (isBenefitType) {
            // TODO
            return
        }
        val isOldHighLightType = LiveRoomUtils.isOldHighLightType(jsonString)
        if (isOldHighLightType) {
            return
        }
        val isNativeHighLight = LiveRoomUtils.isNativeHighLight(jsonString, mLiveId)
        if (isNativeHighLight) {
            // TODO
        }
        val isAnswerType = LiveRoomUtils.isAnswerType(jsonString)
        if (isAnswerType) {
            // TODO
        }
        eventBusFire(WeexEventConstants.WEEX_EVENT_BIND_POWER_MESSAGE_CALLBACK,
                JSONObject.parse(jsonString))
    }

MockPowerMsgEntity.java

public class MockPowerMsgEntity implements Serializable {

    /**
     *  type 1 2 3 分别对应下列3个回调
     *  fun msgLiveOriginalJsonPaserCallBack(jsonString: String?)
     *  fun msgLikeParserCallback(msgLike: MsgLike)
     *  fun msgLiveStatusParserCallback(jsonString: String?, msgLiveStatus: MsgLiveStatus?)
     *
     */
    public int type;  // 对应 PowerMsg 三种回调类型
    public JSONObject data; // 数据类型

}

5. Socket服务端工具

1.安装软件

安装软件: SSokit
SSokit地址

2.步骤参考

1.打开软件,自动识别当前电脑地址,手动输入端口号,如:7653
2.手机摇一摇,输入Ip,端口号,点击设置模拟PowerMsg按钮;打开开关。
3.显示已连接
4.在右侧输入框发送文本,格式参考:

{
    "type": 1,
    "data": {
	    "uniqueKey":"1629428186122:-875441502",
	    "type":1304,
	    "body":{
	        "questionId":12312312312312
	    }
    }

手机端设置参考:手机端设置参考

3.发送消息:

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值