mirror of
https://gitee.com/farsunset/cim.git
synced 2025-06-17 15:45:24 +08:00
修改在android sdk 在低版本中一个兼容问题
This commit is contained in:
parent
27a7c5d2c0
commit
18e7464051
@ -19,7 +19,7 @@
|
|||||||
<entry file="file://$PROJECT_DIR$/pom.xml">
|
<entry file="file://$PROJECT_DIR$/pom.xml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="836">
|
<state relative-caret-position="836">
|
||||||
<caret line="44" column="67" selection-start-line="44" selection-start-column="67" selection-end-line="44" selection-end-column="67" />
|
<caret line="44" column="66" selection-start-line="44" selection-start-column="66" selection-end-line="44" selection-end-column="66" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<file pinned="false" current-in-tab="true">
|
<file pinned="false" current-in-tab="true">
|
||||||
<entry file="file://$PROJECT_DIR$/src/main/java/com/farsunset/cim/CIMConfig.java">
|
<entry file="file://$PROJECT_DIR$/src/main/java/com/farsunset/cim/CIMConfig.java">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="171">
|
<state relative-caret-position="172">
|
||||||
<caret line="57" column="78" selection-start-line="57" selection-start-column="78" selection-end-line="57" selection-end-column="78" />
|
<caret line="57" column="78" selection-start-line="57" selection-start-column="78" selection-end-line="57" selection-end-column="78" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="imports" expanded="true" />
|
<element signature="imports" expanded="true" />
|
||||||
@ -80,7 +80,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds" extendedState="1">
|
<component name="ProjectFrameBounds">
|
||||||
<option name="y" value="23" />
|
<option name="y" value="23" />
|
||||||
<option name="width" value="1920" />
|
<option name="width" value="1920" />
|
||||||
<option name="height" value="1057" />
|
<option name="height" value="1057" />
|
||||||
@ -90,7 +90,6 @@
|
|||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
<pane id="PackagesPane" />
|
|
||||||
<pane id="Scope" />
|
<pane id="Scope" />
|
||||||
<pane id="ProjectPane">
|
<pane id="ProjectPane">
|
||||||
<subPane>
|
<subPane>
|
||||||
@ -143,6 +142,7 @@
|
|||||||
<select />
|
<select />
|
||||||
</subPane>
|
</subPane>
|
||||||
</pane>
|
</pane>
|
||||||
|
<pane id="PackagesPane" />
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
@ -218,16 +218,18 @@
|
|||||||
<workItem from="1559009816995" duration="1293000" />
|
<workItem from="1559009816995" duration="1293000" />
|
||||||
<workItem from="1559110709907" duration="1801000" />
|
<workItem from="1559110709907" duration="1801000" />
|
||||||
<workItem from="1559198165156" duration="1213000" />
|
<workItem from="1559198165156" duration="1213000" />
|
||||||
|
<workItem from="1559269742769" duration="598000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TimeTrackingManager">
|
<component name="TimeTrackingManager">
|
||||||
<option name="totallyTimeSpent" value="7630000" />
|
<option name="totallyTimeSpent" value="8228000" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="0" y="23" width="1920" height="1057" extended-state="1" />
|
<frame x="0" y="23" width="1920" height="1057" extended-state="0" />
|
||||||
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.271123" />
|
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.27433154" />
|
||||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
<window_info id="Designer" order="2" />
|
<window_info id="Designer" order="2" />
|
||||||
<window_info id="UI Designer" order="3" />
|
<window_info id="UI Designer" order="3" />
|
||||||
@ -235,7 +237,7 @@
|
|||||||
<window_info id="Web" order="5" side_tool="true" />
|
<window_info id="Web" order="5" side_tool="true" />
|
||||||
<window_info anchor="bottom" id="Message" order="0" />
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
<window_info anchor="bottom" id="Find" order="1" />
|
<window_info anchor="bottom" id="Find" order="1" />
|
||||||
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.51953536" />
|
<window_info anchor="bottom" id="Run" order="2" weight="0.51953536" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.26821542" />
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.26821542" />
|
||||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
@ -317,7 +319,7 @@
|
|||||||
<entry file="file://$PROJECT_DIR$/pom.xml">
|
<entry file="file://$PROJECT_DIR$/pom.xml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="836">
|
<state relative-caret-position="836">
|
||||||
<caret line="44" column="67" selection-start-line="44" selection-start-column="67" selection-end-line="44" selection-end-column="67" />
|
<caret line="44" column="66" selection-start-line="44" selection-start-column="66" selection-end-line="44" selection-end-column="66" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
@ -337,7 +339,7 @@
|
|||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/src/main/java/com/farsunset/cim/CIMConfig.java">
|
<entry file="file://$PROJECT_DIR$/src/main/java/com/farsunset/cim/CIMConfig.java">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="171">
|
<state relative-caret-position="172">
|
||||||
<caret line="57" column="78" selection-start-line="57" selection-start-column="78" selection-end-line="57" selection-end-column="78" />
|
<caret line="57" column="78" selection-start-line="57" selection-start-column="78" selection-end-line="57" selection-end-column="78" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="imports" expanded="true" />
|
<element signature="imports" expanded="true" />
|
||||||
|
@ -24,7 +24,6 @@ package com.farsunset.cim.sdk.android;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.StandardSocketOptions;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ClosedSelectorException;
|
import java.nio.channels.ClosedSelectorException;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
@ -33,24 +32,25 @@ import java.nio.channels.SocketChannel;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import com.farsunset.cim.sdk.android.coder.CIMLogger;
|
import com.farsunset.cim.sdk.android.coder.CIMLogger;
|
||||||
import com.farsunset.cim.sdk.android.coder.ClientMessageDecoder;
|
import com.farsunset.cim.sdk.android.coder.ClientMessageDecoder;
|
||||||
import com.farsunset.cim.sdk.android.coder.ClientMessageEncoder;
|
import com.farsunset.cim.sdk.android.coder.ClientMessageEncoder;
|
||||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||||
import com.farsunset.cim.sdk.android.exception.SessionClosedException;
|
|
||||||
import com.farsunset.cim.sdk.android.model.HeartbeatRequest;
|
import com.farsunset.cim.sdk.android.model.HeartbeatRequest;
|
||||||
import com.farsunset.cim.sdk.android.model.HeartbeatResponse;
|
import com.farsunset.cim.sdk.android.model.HeartbeatResponse;
|
||||||
import com.farsunset.cim.sdk.android.model.Message;
|
import com.farsunset.cim.sdk.android.model.Message;
|
||||||
|
import com.farsunset.cim.sdk.android.model.Protobufable;
|
||||||
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
||||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@ -60,7 +60,7 @@ import android.os.Process;
|
|||||||
*
|
*
|
||||||
* @author 3979434@qq.com
|
* @author 3979434@qq.com
|
||||||
*/
|
*/
|
||||||
class CIMConnectorManager {
|
class CIMConnectorManager{
|
||||||
|
|
||||||
private static CIMConnectorManager manager;
|
private static CIMConnectorManager manager;
|
||||||
|
|
||||||
@ -79,6 +79,9 @@ class CIMConnectorManager {
|
|||||||
|
|
||||||
private static final HandlerThread IDLE_HANDLER_THREAD = new HandlerThread("READ-IDLE", Process.THREAD_PRIORITY_BACKGROUND);
|
private static final HandlerThread IDLE_HANDLER_THREAD = new HandlerThread("READ-IDLE", Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
|
|
||||||
|
private LinkedBlockingQueue<Protobufable> sendFailBodyQueue = new LinkedBlockingQueue<Protobufable>();
|
||||||
|
private final ReentrantLock IOLOCK = new ReentrantLock();
|
||||||
|
|
||||||
private Selector selector;
|
private Selector selector;
|
||||||
private SocketChannel socketChannel ;
|
private SocketChannel socketChannel ;
|
||||||
private Context context;
|
private Context context;
|
||||||
@ -106,10 +109,10 @@ class CIMConnectorManager {
|
|||||||
if(socketChannel == null || !socketChannel.isOpen()) {
|
if(socketChannel == null || !socketChannel.isOpen()) {
|
||||||
socketChannel = SocketChannel.open();
|
socketChannel = SocketChannel.open();
|
||||||
socketChannel.configureBlocking(false);
|
socketChannel.configureBlocking(false);
|
||||||
socketChannel.setOption(StandardSocketOptions.SO_RCVBUF,READ_BUFFER_SIZE);
|
socketChannel.socket().setTcpNoDelay(true);
|
||||||
socketChannel.setOption(StandardSocketOptions.SO_SNDBUF, WRITE_BUFFER_SIZE);
|
socketChannel.socket().setKeepAlive(true);
|
||||||
socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
|
socketChannel.socket().setReceiveBufferSize(READ_BUFFER_SIZE);
|
||||||
socketChannel.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
socketChannel.socket().setSendBufferSize(WRITE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selector == null || !selector.isOpen()) {
|
if(selector == null || !selector.isOpen()) {
|
||||||
@ -135,7 +138,9 @@ class CIMConnectorManager {
|
|||||||
|
|
||||||
public void connect(final String host, final int port) {
|
public void connect(final String host, final int port) {
|
||||||
|
|
||||||
if (!isNetworkConnected(context)) {
|
boolean isNetworkConnected = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetwork() != null;
|
||||||
|
|
||||||
|
if (!isNetworkConnected) {
|
||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setPackage(context.getPackageName());
|
intent.setPackage(context.getPackageName());
|
||||||
@ -145,8 +150,7 @@ class CIMConnectorManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConnected = isConnected();
|
if (CONNECTING_FLAG.get() || isConnected()) {
|
||||||
if (CONNECTING_FLAG.get() || isConnected) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +164,8 @@ class CIMConnectorManager {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
|
IOLOCK.lock();
|
||||||
|
|
||||||
LOGGER.startConnect(host, port);
|
LOGGER.startConnect(host, port);
|
||||||
|
|
||||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||||
@ -179,6 +185,7 @@ class CIMConnectorManager {
|
|||||||
for(SelectionKey key : selector.selectedKeys()){
|
for(SelectionKey key : selector.selectedKeys()){
|
||||||
|
|
||||||
if((key.interestOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT && socketChannel.finishConnect()) {
|
if((key.interestOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT && socketChannel.finishConnect()) {
|
||||||
|
IOLOCK.unlock();
|
||||||
handelConnectedEvent();
|
handelConnectedEvent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -199,8 +206,161 @@ class CIMConnectorManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
closeSession();
|
||||||
|
closeSelector();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void closeSession() {
|
||||||
|
try {
|
||||||
|
socketChannel.close();
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
}finally {
|
||||||
|
this.sessionClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected() {
|
||||||
|
return socketChannel != null && socketChannel.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void send(final Protobufable body) {
|
||||||
|
|
||||||
|
bossExecutor.execute(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
|
||||||
|
IOLOCK.lock();
|
||||||
|
|
||||||
|
ByteBuffer buffer = messageEncoder.encode(body);
|
||||||
|
while(buffer.hasRemaining()){
|
||||||
|
result += socketChannel.write(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
result = -1;
|
||||||
|
}finally {
|
||||||
|
|
||||||
|
IOLOCK.unlock();
|
||||||
|
|
||||||
|
if(result <= 0) {
|
||||||
|
sendFailBodyQueue.offer(body);
|
||||||
|
closeSession();
|
||||||
|
}else {
|
||||||
|
messageSent(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendFaildQueueBody() {
|
||||||
|
Protobufable body = sendFailBodyQueue.poll();
|
||||||
|
if(body == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
send(body);
|
||||||
|
|
||||||
|
sendFaildQueueBody();
|
||||||
|
|
||||||
|
}
|
||||||
|
private void sessionCreated() {
|
||||||
|
LOGGER.sessionCreated(socketChannel);
|
||||||
|
|
||||||
|
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
|
||||||
|
sendFaildQueueBody();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sessionClosed() {
|
||||||
|
|
||||||
|
idleHandler.removeMessages(0);
|
||||||
|
|
||||||
|
LAST_READ_TIME.set(0);
|
||||||
|
|
||||||
|
LOGGER.sessionClosed(socketChannel);
|
||||||
|
|
||||||
|
readBuffer.clear();
|
||||||
|
|
||||||
|
if(readBuffer.capacity() > READ_BUFFER_SIZE) {
|
||||||
|
readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
closeSelector();
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sessionIdle() {
|
||||||
|
|
||||||
|
LOGGER.sessionIdle(socketChannel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于解决,wifi情况下。偶而路由器与服务器断开连接时,客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (System.currentTimeMillis() - LAST_READ_TIME.get() >= CONNECT_ALIVE_TIME_OUT) {
|
||||||
|
closeSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void messageReceived(Object obj) {
|
||||||
|
|
||||||
|
if (obj instanceof Message) {
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
|
||||||
|
intent.putExtra(Message.class.getName(), (Message) obj);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (obj instanceof ReplyBody) {
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
|
||||||
|
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void messageSent(Object message) {
|
||||||
|
|
||||||
|
LOGGER.messageSent(socketChannel, message);
|
||||||
|
|
||||||
|
if (message instanceof SentBody) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED);
|
||||||
|
intent.putExtra(SentBody.class.getName(), (SentBody) message);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Handler idleHandler = new Handler(IDLE_HANDLER_THREAD.getLooper()) {
|
private Handler idleHandler = new Handler(IDLE_HANDLER_THREAD.getLooper()) {
|
||||||
public void handleMessage(android.os.Message m) {
|
public void handleMessage(android.os.Message m) {
|
||||||
sessionIdle();
|
sessionIdle();
|
||||||
@ -239,12 +399,6 @@ class CIMConnectorManager {
|
|||||||
|
|
||||||
private void handelSocketReadEvent() throws IOException {
|
private void handelSocketReadEvent() throws IOException {
|
||||||
|
|
||||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
|
||||||
|
|
||||||
idleHandler.removeMessages(0);
|
|
||||||
|
|
||||||
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
while((result = socketChannel.read(readBuffer)) > 0) {
|
while((result = socketChannel.read(readBuffer)) > 0) {
|
||||||
@ -257,6 +411,10 @@ class CIMConnectorManager {
|
|||||||
closeSession();
|
closeSession();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
markLastReadTime();
|
||||||
|
|
||||||
|
|
||||||
readBuffer.position(0);
|
readBuffer.position(0);
|
||||||
|
|
||||||
@ -266,6 +424,8 @@ class CIMConnectorManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LOGGER.messageReceived(socketChannel,message);
|
LOGGER.messageReceived(socketChannel,message);
|
||||||
|
|
||||||
if(isHeartbeatRequest(message)) {
|
if(isHeartbeatRequest(message)) {
|
||||||
@ -288,190 +448,30 @@ class CIMConnectorManager {
|
|||||||
readBuffer.clear();
|
readBuffer.clear();
|
||||||
readBuffer = newBuffer;
|
readBuffer = newBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void markLastReadTime() {
|
||||||
|
|
||||||
|
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||||
|
|
||||||
|
idleHandler.removeMessages(0);
|
||||||
|
|
||||||
|
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void send(final SentBody body) {
|
|
||||||
|
|
||||||
bossExecutor.execute(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
boolean isSuccessed = false;
|
|
||||||
String exceptionName = SessionClosedException.class.getSimpleName();
|
|
||||||
if (isConnected()) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
ByteBuffer buffer = messageEncoder.encode(body);
|
|
||||||
int result = 0;
|
|
||||||
while(buffer.hasRemaining()){
|
|
||||||
result += socketChannel.write(buffer);
|
|
||||||
}
|
|
||||||
isSuccessed = result > 0;
|
|
||||||
} catch (IOException e) {
|
|
||||||
exceptionName = e.getClass().getSimpleName();
|
|
||||||
closeSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSuccessed) {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_FAILED);
|
|
||||||
intent.putExtra(Exception.class.getName(), exceptionName);
|
|
||||||
intent.putExtra(SentBody.class.getName(), body);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}else {
|
|
||||||
messageSent(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void send(final HeartbeatResponse body) {
|
|
||||||
|
|
||||||
bossExecutor.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
socketChannel.write(messageEncoder.encode(body));
|
|
||||||
messageSent(body);
|
|
||||||
} catch (IOException ignore) {
|
|
||||||
closeSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private HeartbeatResponse getHeartbeatResponse() {
|
||||||
public void sessionCreated() {
|
|
||||||
LOGGER.sessionCreated(socketChannel);
|
|
||||||
|
|
||||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
|
||||||
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sessionClosed() {
|
|
||||||
|
|
||||||
idleHandler.removeMessages(0);
|
|
||||||
|
|
||||||
LAST_READ_TIME.set(0);
|
|
||||||
|
|
||||||
LOGGER.sessionClosed(socketChannel);
|
|
||||||
|
|
||||||
readBuffer.clear();
|
|
||||||
|
|
||||||
if(readBuffer.capacity() > READ_BUFFER_SIZE) {
|
|
||||||
readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
closeSelector();
|
|
||||||
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sessionIdle() {
|
|
||||||
|
|
||||||
LOGGER.sessionIdle(socketChannel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于解决,wifi情况下。偶而路由器与服务器断开连接时,客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if (System.currentTimeMillis() - LAST_READ_TIME.get() >= CONNECT_ALIVE_TIME_OUT) {
|
|
||||||
closeSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void messageReceived(Object obj) {
|
|
||||||
|
|
||||||
if (obj instanceof Message) {
|
|
||||||
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
|
|
||||||
intent.putExtra(Message.class.getName(), (Message) obj);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (obj instanceof ReplyBody) {
|
|
||||||
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
|
|
||||||
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void messageSent(Object message) {
|
|
||||||
|
|
||||||
LOGGER.messageSent(socketChannel, message);
|
|
||||||
|
|
||||||
if (message instanceof SentBody) {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setPackage(context.getPackageName());
|
|
||||||
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED);
|
|
||||||
intent.putExtra(SentBody.class.getName(), (SentBody) message);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNetworkConnected(Context context) {
|
|
||||||
try {
|
|
||||||
ConnectivityManager nw = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo networkInfo = nw.getActiveNetworkInfo();
|
|
||||||
return networkInfo != null;
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public HeartbeatResponse getHeartbeatResponse() {
|
|
||||||
return HeartbeatResponse.getInstance();
|
return HeartbeatResponse.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHeartbeatRequest(Object data) {
|
private boolean isHeartbeatRequest(Object data) {
|
||||||
return data instanceof HeartbeatRequest;
|
return data instanceof HeartbeatRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
|
|
||||||
closeSession();
|
|
||||||
closeSelector();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConnected() {
|
private void closeSelector() {
|
||||||
return socketChannel != null && socketChannel.isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeSession() {
|
|
||||||
try {
|
|
||||||
socketChannel.close();
|
|
||||||
} catch (IOException ignore) {
|
|
||||||
}finally {
|
|
||||||
this.sessionClosed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeSelector() {
|
|
||||||
try {
|
try {
|
||||||
selector.close();
|
selector.close();
|
||||||
} catch (IOException ignore) {}
|
} catch (IOException ignore) {}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
package com.farsunset.cim.sdk.android;
|
package com.farsunset.cim.sdk.android;
|
||||||
|
|
||||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||||
import com.farsunset.cim.sdk.android.exception.SessionClosedException;
|
|
||||||
import com.farsunset.cim.sdk.android.model.Message;
|
import com.farsunset.cim.sdk.android.model.Message;
|
||||||
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
||||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||||
@ -102,15 +101,7 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
|
|||||||
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED)) {
|
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED)) {
|
||||||
onReplyReceived((ReplyBody) intent.getSerializableExtra(ReplyBody.class.getName()));
|
onReplyReceived((ReplyBody) intent.getSerializableExtra(ReplyBody.class.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 获取sendbody发送失败事件
|
|
||||||
*/
|
|
||||||
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_FAILED)) {
|
|
||||||
String exceptionName = intent.getStringExtra(Exception.class.getName());
|
|
||||||
SentBody sentBody = (SentBody) intent.getSerializableExtra(SentBody.class.getName());
|
|
||||||
onSentFailed(exceptionName, sentBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 获取sendbody发送成功事件
|
* 获取sendbody发送成功事件
|
||||||
@ -142,7 +133,9 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
private void onInnerConnectionClosed() {
|
private void onInnerConnectionClosed() {
|
||||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||||
if (CIMConnectorManager.isNetworkConnected(context)) {
|
boolean isNetworkConnected = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetwork() != null;
|
||||||
|
|
||||||
|
if (isNetworkConnected) {
|
||||||
CIMPushManager.connect(context, 0);
|
CIMPushManager.connect(context, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +143,9 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onConnectionFailed(long reinterval) {
|
private void onConnectionFailed(long reinterval) {
|
||||||
|
boolean isNetworkConnected = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetwork() != null;
|
||||||
|
|
||||||
if (CIMConnectorManager.isNetworkConnected(context)) {
|
if (isNetworkConnected) {
|
||||||
onConnectionFailed();
|
onConnectionFailed();
|
||||||
|
|
||||||
CIMPushManager.connect(context, reinterval);
|
CIMPushManager.connect(context, reinterval);
|
||||||
@ -185,18 +179,7 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
|
|||||||
private boolean isForceOfflineMessage(String action) {
|
private boolean isForceOfflineMessage(String action) {
|
||||||
return CIMConstant.MessageAction.ACTION_999.equals(action);
|
return CIMConstant.MessageAction.ACTION_999.equals(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSentFailed(String exceptionName, SentBody body) {
|
|
||||||
|
|
||||||
// 与服务端端开链接,重新连接
|
|
||||||
if (SessionClosedException.class.getSimpleName().equals(exceptionName)) {
|
|
||||||
CIMPushManager.connect(context, 0);
|
|
||||||
} else {
|
|
||||||
// 发送失败 重新发送
|
|
||||||
CIMPushManager.sendRequest(context, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void onMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent);
|
public abstract void onMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent);
|
||||||
|
|
||||||
|
@ -117,16 +117,16 @@ public class CIMLogger {
|
|||||||
builder.append("id:").append(session.hashCode());
|
builder.append("id:").append(session.hashCode());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (session.getLocalAddress() != null) {
|
if (session.socket().getLocalAddress() != null) {
|
||||||
builder.append(" L:").append(session.getLocalAddress().toString());
|
builder.append(" L:").append(session.socket().getLocalAddress().toString());
|
||||||
}
|
}
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (session.getRemoteAddress() != null) {
|
if (session.socket().getRemoteSocketAddress() != null) {
|
||||||
builder.append(" R:").append(session.getRemoteAddress().toString());
|
builder.append(" R:").append(session.socket().getRemoteSocketAddress().toString());
|
||||||
}
|
}
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,6 @@ public interface CIMConstant {
|
|||||||
// 消息广播action
|
// 消息广播action
|
||||||
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
|
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
|
||||||
|
|
||||||
// 发送sendbody失败广播
|
|
||||||
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
|
|
||||||
|
|
||||||
// 发送sendbody成功广播
|
// 发送sendbody成功广播
|
||||||
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
|
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
|
||||||
|
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
***************************************************************************************
|
|
||||||
* *
|
|
||||||
* Website : http://www.farsunset.com *
|
|
||||||
* *
|
|
||||||
***************************************************************************************
|
|
||||||
*/
|
|
||||||
package com.farsunset.cim.sdk.android.exception;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class NetworkDisabledException extends Exception implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public NetworkDisabledException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkDisabledException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
***************************************************************************************
|
|
||||||
* *
|
|
||||||
* Website : http://www.farsunset.com *
|
|
||||||
* *
|
|
||||||
***************************************************************************************
|
|
||||||
*/
|
|
||||||
package com.farsunset.cim.sdk.android.exception;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class SessionClosedException extends Exception implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public SessionClosedException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SessionClosedException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user