一、前言:为了公司研究推送和保活方案
尝试了以Android作为Socket长连接的服务端server,以后台作为Socket的客户端client,后台进行推送,这样的目的是保证,后台不需要长时间连接多个设备,后台每次有新的消息,创建多个Client通过Socket推送给Android终端设备,数据传输完成后,所有的client终端关闭,释放资源。而Android作为SocketServer一直监听端口,处于挂起状态,所以保证了推送数据的实时性。当然这种做法缺点很明显:1.Android长期挂起耗电,2.一旦Android终端程序被杀,无法推送到手机,3.Android应用层没有真正的保活,4.也是最大的问题Android终端能通过3G、4G上网,WIFI上网,VPN翻墙上网,作为SocketServer需要提供公网的IP,因此Android端的IP是多少?怎么获取?
二、开发过程:
2.1、带着以上问题,进行Demo的编写和测试
2.2 开发环境:Android 5.1设备,后台Springboot集成的Tomcat服务
2.3 具体代码:
后台代码
@RequestMapping("/efss/test")
@RestController
public class TestController extends BaseController {
@RequestMapping("/uploadTerminalIp")
public ApiResponse<Object> uploadTerminalIp(@RequestBody String json) {
JSONObject jsonObject = JSONObject.parseObject(json);
JSONObject jsonData = jsonObject.getJSONObject("nameValuePairs");
String ip = jsonData.getString("ip");
Integer port = jsonData.getInteger("port");
if (StringUtils.isBlank(ip)) {
return apiFail("ip地址为空");
}
if (null == port) {
return apiFail("port为空");
}
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
String currentTimeStr = TimeUtil.getDate2String(new Date(), "yyyy-MM-dd HH:mm:ss") + ",随机码:" + new Random().nextFloat();
String responseStr = SocketUtil.tcpPost(ip, port.toString(), currentTimeStr);
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return apiSuccess("Socket connected....!!!.............");
}
}
模拟后台接口中直接写了一个定时,每5秒通过Socket向Android发送一个时间。
贴下SocketUtil 只负责写(推送消息),不读,当然如果需要自己添加实现
/**
* * Created by jambestwick@126.com
* * on 2019/5/31
* *
*/
public class SocketUtil {
private static final Logger logger = LoggerFactory.getLogger(SocketUtil.class);
/**
* 发送socket请求
*
* @param clientIp
* @param clientPort
* @param msg
* @return
*/
public static synchronized String tcpPost(String clientIp, String clientPort, String msg) {
String rs = "";
if (clientIp == null || "".equals(clientIp) || clientPort == null || "".equals(clientPort)) {
logger.error("Ip或端口不存在...");
return null;
}
int clientPortInt = Integer.parseInt(clientPort);
logger.info("clientIp:" + clientIp + " clientPort:" + clientPort);
Socket s = null;
OutputStream out = null;
//InputStream in = null;
try {
s = new Socket(clientIp, clientPortInt);
s.setSendBufferSize(4096);
s.setTcpNoDelay(true);
s.setSoTimeout(60 * 1000);
s.setKeepAlive(true);
out = s.getOutputStream();
//in = s.getI