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 {
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);
recv_buff = new String(buffer);
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) {
return
}
val isOldHighLightType = LiveRoomUtils.isOldHighLightType(jsonString)
if (isOldHighLightType) {
return
}
val isNativeHighLight = LiveRoomUtils.isNativeHighLight(jsonString, mLiveId)
if (isNativeHighLight) {
}
val isAnswerType = LiveRoomUtils.isAnswerType(jsonString)
if (isAnswerType) {
}
eventBusFire(WeexEventConstants.WEEX_EVENT_BIND_POWER_MESSAGE_CALLBACK,
JSONObject.parse(jsonString))
}
MockPowerMsgEntity.java
public class MockPowerMsgEntity implements Serializable {
public int type;
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.发送消息:
|