对websdk和javasdk增加了处理下线的逻辑

This commit is contained in:
远方夕阳 2018-02-05 17:58:41 +08:00
parent 13805095b5
commit 627e2bcd9a
163 changed files with 26222 additions and 27614 deletions

View File

@ -26,86 +26,76 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
class CIMCacheManager {
class CIMCacheManager {
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
public static final String KEY_DEVICE_ID = "KEY_DEVICE_ID";
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
public static final String KEY_CIM_SERVIER_HOST = "KEY_CIM_SERVIER_HOST";
public static final String KEY_CIM_SERVIER_PORT = "KEY_CIM_SERVIER_PORT";
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
public static void remove(Context context ,String key)
{
ContentResolver resolver = context.getContentResolver();
public static void remove(Context context, String key) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(Uri.parse(CIMCacheProvider.CONTENT_URI), key, null);
}
public static void putString(Context context, String key, String value) {
public static void putString(Context context ,String key,String value)
{
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("value", value);
values.put("key", key);
resolver.insert(Uri.parse(CIMCacheProvider.CONTENT_URI), values);
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("value", value);
values.put("key", key);
resolver.insert(Uri.parse(CIMCacheProvider.CONTENT_URI), values);
}
public static String getString(Context context ,String key)
{
public static String getString(Context context, String key) {
String value = null;
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(CIMCacheProvider.CONTENT_URI), new String[]{key}, null,null,null);
if (cursor!=null && cursor.moveToFirst())
{
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(CIMCacheProvider.CONTENT_URI), new String[] { key }, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
value = cursor.getString(0);
cursor.close();
}
closeQuietly(cursor);
return value;
}
private static void closeQuietly(Cursor cursor){
try{
if(cursor!=null)
cursor.close();
}catch(Exception e){}
private static void closeQuietly(Cursor cursor) {
try {
if (cursor != null)
cursor.close();
} catch (Exception e) {
}
}
public static void putBoolean(Context context,String key,boolean value)
{
putString(context,key,Boolean.toString(value));
public static void putBoolean(Context context, String key, boolean value) {
putString(context, key, Boolean.toString(value));
}
public static boolean getBoolean(Context context,String key)
{
String value = getString(context,key);
return value == null?false:Boolean.parseBoolean(value);
public static boolean getBoolean(Context context, String key) {
String value = getString(context, key);
return value == null ? false : Boolean.parseBoolean(value);
}
public static void putInt(Context context,String key,int value)
{
putString(context,key, String.valueOf(value));
public static void putInt(Context context, String key, int value) {
putString(context, key, String.valueOf(value));
}
public static int getInt(Context context,String key)
{
String value = getString(context,key);
return value == null?0:Integer.parseInt(value);
public static int getInt(Context context, String key) {
String value = getString(context, key);
return value == null ? 0 : Integer.parseInt(value);
}
}

View File

@ -29,13 +29,12 @@ import android.database.MatrixCursor;
import android.net.Uri;
public class CIMCacheProvider extends ContentProvider {
public static final String CONTENT_URI="content://com.farsunset.cim.provider";
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
public static final String CONTENT_URI = "content://com.farsunset.cim.provider";
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
@Override
public int delete(Uri arg0, String key, String[] arg2) {
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
return 0;
}
@ -48,7 +47,7 @@ public class CIMCacheProvider extends ContentProvider {
public Uri insert(Uri arg0, ContentValues values) {
String key = values.getAsString("key");
String value = values.getAsString("value");
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
return null;
}
@ -59,9 +58,9 @@ public class CIMCacheProvider extends ContentProvider {
@Override
public Cursor query(Uri arg0, String[] arg1, String key, String[] arg3, String arg4) {
MatrixCursor cursor = new MatrixCursor(new String[]{"value"});
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
cursor.addRow(new Object[]{value});
MatrixCursor cursor = new MatrixCursor(new String[] { "value" });
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
cursor.addRow(new Object[] { value });
return cursor;
}
@ -70,5 +69,4 @@ public class CIMCacheProvider extends ContentProvider {
return 0;
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Random;
@ -57,25 +58,23 @@ import com.farsunset.cim.sdk.android.model.SentBody;
*
* @author 3979434@qq.com
*/
class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageFactory {
class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageFactory {
private final String TAG = CIMConnectorManager.class.getSimpleName();
private final int READ_BUFFER_SIZE = 2048;//bit
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int READ_BUFFER_SIZE = 2048;// bit
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int READ_IDLE_TIME = 120;//
private final int READ_IDLE_TIME = 120;//
private final int HEARBEAT_TIME_OUT = (READ_IDLE_TIME + 10) * 1000;// 收到服务端心跳请求超时时间 毫秒
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME" ;
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME";
private NioSocketConnector connector;
private ConnectFuture connectFuture;
private ExecutorService executor = Executors.newFixedThreadPool(1);
private Context context;
private static CIMConnectorManager manager;
private static CIMConnectorManager manager;
private CIMConnectorManager(Context ctx) {
context = ctx;
@ -85,15 +84,15 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
connector.getSessionConfig().setTcpNoDelay(true);
connector.getSessionConfig().setKeepAlive(true);
connector.getSessionConfig().setReadBufferSize(READ_BUFFER_SIZE);
KeepAliveFilter keepAliveaHandler = new KeepAliveFilter(this);
keepAliveaHandler.setRequestInterval(READ_IDLE_TIME);
keepAliveaHandler.setRequestTimeoutHandler(KeepAliveRequestTimeoutHandler.NOOP);
keepAliveaHandler.setForwardEvent(true);
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ClientMessageCodecFactory()));
connector.getFilterChain().addLast("heartbeat", keepAliveaHandler);
connector.setHandler(this);
}
@ -106,88 +105,85 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
}
private synchronized void syncConnection(final String host,final int port) {
if(isConnected()){
return ;
private synchronized void syncConnection(final String host, final int port) {
if (isConnected()) {
return;
}
try {
Log.i(TAG, "****************CIM正在连接服务器 "+host+":"+port+"......");
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
Log.i(TAG, "****************CIM正在连接服务器 " + host + ":" + port + "......");
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
InetSocketAddress remoteSocketAddress = new InetSocketAddress(host, port);
connectFuture = connector.connect(remoteSocketAddress);
connectFuture.awaitUninterruptibly();
connectFuture.getSession();
} catch (Exception e) {
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5*1000 - new Random().nextInt(15*1000));
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5 * 1000 - new Random().nextInt(15 * 1000));
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED);
intent.putExtra(Exception.class.getName(), e.getClass().getSimpleName());
intent.putExtra("interval", interval);
context.sendBroadcast(intent);
Log.e(TAG, "****************CIM连接服务器失败 "+host+":"+port+"......将在"+interval/1000+"秒后重新尝试连接");
}
Log.e(TAG, "****************CIM连接服务器失败 " + host + ":" + port + "......将在" + interval / 1000 + "秒后重新尝试连接");
}
}
public void connect(final String host, final int port) {
if (!isNetworkConnected(context)) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED);
intent.putExtra(Exception.class.getName(),NetworkDisabledException.class.getSimpleName());
intent.putExtra(Exception.class.getName(), NetworkDisabledException.class.getSimpleName());
context.sendBroadcast(intent);
return;
}
executor.execute(new Runnable() {
public void run()
{
public void run() {
syncConnection(host, port);
}
}
});
}
public synchronized void send(SentBody body) {
boolean isSuccessed = false;
String exceptionName =SessionClosedException.class.getSimpleName();
String exceptionName = SessionClosedException.class.getSimpleName();
IoSession session = getCurrentSession();
if(session!=null && session.isConnected())
{
if (session != null && session.isConnected()) {
WriteFuture wf = session.write(body);
// 消息发送超时 5秒
wf.awaitUninterruptibly(WRITE_TIMEOUT);
isSuccessed = wf.isWritten();
if(wf.getException() != null)
{
exceptionName =wf.getException().getClass().getSimpleName();
if (wf.getException() != null) {
exceptionName = wf.getException().getClass().getSimpleName();
}
}
if(!isSuccessed){
}
if (!isSuccessed) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_FAILED);
intent.putExtra(Exception.class.getName(),exceptionName);
intent.putExtra(Exception.class.getName(), exceptionName);
intent.putExtra(SentBody.class.getName(), body);
context.sendBroadcast(intent);
}
}
public void destroy() {
public void destroy() {
IoSession session = getCurrentSession();
if (session != null) {
session.closeNow();
@ -196,59 +192,51 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
if (connector != null && !connector.isDisposed()) {
connector.dispose();
}
manager = null;
}
public boolean isConnected() {
IoSession session = getCurrentSession();
return session != null ;
return session != null;
}
public void closeSession()
{
public void closeSession() {
IoSession session = getCurrentSession();
if(session!=null)
{
if (session != null) {
session.closeNow();
}
}
public IoSession getCurrentSession()
{
Map<Long,IoSession> sessions = connector.getManagedSessions();
for(Long key:sessions.keySet())
{
public IoSession getCurrentSession() {
Map<Long, IoSession> sessions = connector.getManagedSessions();
for (Long key : sessions.keySet()) {
IoSession session = sessions.get(key);
if(session.isConnected()){
if (session.isConnected()) {
return session;
}
}
return null;
}
@Override
public void sessionCreated(IoSession session) throws Exception {
Log.i(TAG, "****************CIM连接服务器成功:"+session.getLocalAddress()+" NID:"+session.getId());
Log.i(TAG, "****************CIM连接服务器成功:" + session.getLocalAddress() + " NID:" + session.getId());
setLastHeartbeatTime(session);
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED);
context.sendBroadcast(intent);
}
@Override
public void sessionClosed(IoSession session) {
Log.e(TAG, "****************CIM与服务器断开连接:"+session.getLocalAddress()+" NID:"+session.getId());
Log.e(TAG, "****************CIM与服务器断开连接:" + session.getLocalAddress() + " NID:" + session.getId());
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
context.sendBroadcast(intent);
@ -256,45 +244,44 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
Log.d(TAG, "****************CIM "+status.toString().toUpperCase()+":"+session.getLocalAddress() +" NID:"+session.getId()+ " isConnected:" + session.isConnected());
public void sessionIdle(IoSession session, IdleStatus status) {
Log.d(TAG, "****************CIM " + status.toString().toUpperCase() + ":" + session.getLocalAddress() + " NID:"
+ session.getId() + " isConnected:" + session.isConnected());
/**
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件
* 导致这样的情况下当前连接无效也不会重连的问题
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
*
*/
long lastHeartbeatTime = getLastHeartbeatTime(session);
if(System.currentTimeMillis() - lastHeartbeatTime >= HEARBEAT_TIME_OUT)
{
if (System.currentTimeMillis() - lastHeartbeatTime >= HEARBEAT_TIME_OUT) {
session.closeNow();
Log.e(TAG, "****************CIM心跳超时 ,即将重新连接......"+" NID:"+session.getId());
Log.e(TAG, "****************CIM心跳超时 ,即将重新连接......" + " NID:" + session.getId());
}
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
Log.e(TAG, "****************CIM连接出现未知异常:"+session.getLocalAddress()+" NID:"+session.getId());
if(cause!=null && cause.getMessage()!=null){
Log.e(TAG, "****************CIM连接出现未知异常:" + session.getLocalAddress() + " NID:" + session.getId());
if (cause != null && cause.getMessage() != null) {
Log.e(TAG, cause.getMessage());
}
}
@Override
public void messageReceived(IoSession session, Object obj){
public void messageReceived(IoSession session, Object obj) {
if (obj instanceof Message) {
Intent intent = new Intent();
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.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
@ -304,42 +291,38 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
@Override
public void messageSent(IoSession session, Object message) {
if(message instanceof SentBody)
{
if (message instanceof SentBody) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED);
intent.putExtra(SentBody.class.getName(), (SentBody) message);
context.sendBroadcast(intent);
}
}
private void setLastHeartbeatTime(IoSession session)
{
private void setLastHeartbeatTime(IoSession session) {
session.setAttribute(KEY_LAST_HEART_TIME, System.currentTimeMillis());
}
private long getLastHeartbeatTime(IoSession session)
{
private long getLastHeartbeatTime(IoSession session) {
long time = 0;
Object value = session.getAttribute(KEY_LAST_HEART_TIME);
if(value !=null){
if (value != null) {
time = Long.parseLong(value.toString());
}
return time;
}
public static boolean isNetworkConnected(Context context) {
try {
ConnectivityManager nw = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = nw.getActiveNetworkInfo();
return networkInfo != null;
} catch (Exception e) {}
} catch (Exception e) {
}
return false;
}
@Override
public Object getRequest(IoSession arg0) {
return null;
@ -352,9 +335,9 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
@Override
public boolean isRequest(IoSession session, Object data) {
setLastHeartbeatTime(session);
return data instanceof HeartbeatRequest;
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.android;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
import com.farsunset.cim.sdk.android.exception.SessionClosedException;
import com.farsunset.cim.sdk.android.model.Message;
@ -33,207 +32,185 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
* 消息入口所有消息都会经过这里
* 消息入口所有消息都会经过这里
*/
public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver{
public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
protected Context context;
@Override
public void onReceive(Context ctx, Intent intent) {
context = ctx;
/*
* 操作事件广播用于提高service存活率
*/
if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)
||intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)
||intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED))
{
startPushService();
}
context = ctx;
/*
* 设备网络状态变化事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED))
{
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
onDevicesNetworkChanged(connectivityManager.getActiveNetworkInfo());
}
/*
* cim断开服务器事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED))
{
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED))
{
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
String exceptionName = intent.getStringExtra(Exception.class.getName());
onConnectionFailed(exceptionName,interval);
}
/*
* cim连接服务器成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED))
{
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED))
{
onInnerMessageReceived((Message)intent.getSerializableExtra(Message.class.getName()),intent);
}
/*
* 获取收到replybody成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED))
{
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发送成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED))
{
onSentSucceed((SentBody)intent.getSerializableExtra(SentBody.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY))
{
CIMPushManager.connect(context,0);
}
/*
* 操作事件广播用于提高service存活率
*/
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)
|| intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)
|| intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
startPushService();
}
/*
* 设备网络状态变化事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED)) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
onDevicesNetworkChanged(connectivityManager.getActiveNetworkInfo());
}
/*
* cim断开服务器事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED)) {
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED)) {
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
String exceptionName = intent.getStringExtra(Exception.class.getName());
onConnectionFailed(exceptionName, interval);
}
/*
* cim连接服务器成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED)) {
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED)) {
onInnerMessageReceived((Message) intent.getSerializableExtra(Message.class.getName()), intent);
}
/*
* 获取收到replybody成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED)) {
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发送成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED)) {
onSentSucceed((SentBody) intent.getSerializableExtra(SentBody.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY)) {
CIMPushManager.connect(context, 0);
}
}
private void startPushService(){
Intent intent = new Intent(context, CIMPushService.class);
private void startPushService() {
Intent intent = new Intent(context, CIMPushService.class);
intent.setAction(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE);
context.startService(intent);
}
private void onInnerConnectionClosed(){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
if(CIMConnectorManager.isNetworkConnected(context))
{
CIMPushManager.connect(context,0);
private void onInnerConnectionClosed() {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
if (CIMConnectorManager.isNetworkConnected(context)) {
CIMPushManager.connect(context, 0);
}
onConnectionClosed();
}
private void onConnectionFailed(String exceptionName,long reinterval){
if(CIMConnectorManager.isNetworkConnected(context))
{
private void onConnectionFailed(String exceptionName, long reinterval) {
if (CIMConnectorManager.isNetworkConnected(context)) {
onConnectionFailed();
CIMPushManager.connect(context,reinterval);
CIMPushManager.connect(context, reinterval);
}
}
private void onInnerConnectionSuccessed(){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
private void onInnerConnectionSuccessed() {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
boolean autoBind = CIMPushManager.autoBindAccount(context);
onConnectionSuccessed(autoBind);
}
private void onDevicesNetworkChanged(NetworkInfo info) {
if(info !=null)
{
CIMPushManager.connect(context,0);
}
private void onDevicesNetworkChanged(NetworkInfo info) {
if (info != null) {
CIMPushManager.connect(context, 0);
}
onNetworkChanged(info);
}
private void onInnerMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent){
if(isForceOfflineMessage(message.getAction()))
{
private void onInnerMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent) {
if (isForceOfflineMessage(message.getAction())) {
CIMPushManager.stop(context);
}
onMessageReceived(message,intent);
}
private boolean isForceOfflineMessage(String 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);
}
onMessageReceived(message, intent);
}
public abstract void onMessageReceived(com.farsunset.cim.sdk.android.model.Message message,Intent intent);
public void onNetworkChanged(NetworkInfo info) {
private boolean isForceOfflineMessage(String 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 void onNetworkChanged(NetworkInfo info) {
CIMListenerManager.notifyOnNetworkChanged(info);
}
public void onConnectionSuccessed(boolean hasAutoBind) {
public void onConnectionSuccessed(boolean hasAutoBind) {
CIMListenerManager.notifyOnConnectionSuccessed(hasAutoBind);
}
public void onConnectionClosed() {
public void onConnectionClosed() {
CIMListenerManager.notifyOnConnectionClosed();
}
public void onConnectionFailed() {
public void onConnectionFailed() {
CIMListenerManager.notifyOnConnectionFailed();
}
public void onReplyReceived(ReplyBody body) {
public void onReplyReceived(ReplyBody body) {
CIMListenerManager.notifyOnReplyReceived(body);
}
public void onSentSucceed(SentBody body){
public void onSentSucceed(SentBody body) {
CIMListenerManager.notifyOnSentSucceed(body);
}
}

View File

@ -28,59 +28,60 @@ import com.farsunset.cim.sdk.android.model.ReplyBody;
import com.farsunset.cim.sdk.android.model.SentBody;
/**
*CIM 主要事件接口
* CIM 主要事件接口
*/
public interface CIMEventListener
{
public interface CIMEventListener {
/**
* 当收到服务端推送过来的消息时调用
*
* @param message
*/
void onMessageReceived(Message message);
/**
* 当收到服务端推送过来的消息时调用
* @param message
*/
void onMessageReceived(Message message);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
*
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
*
* @param body
*/
void onSentSuccessed(SentBody body);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
* @param body
*/
void onSentSuccessed(SentBody body);
/**
* 当手机网络发生变化时调用
*
* @param networkinfo
*/
void onNetworkChanged(NetworkInfo networkinfo);
/**
* 当手机网络发生变化时调用
* @param networkinfo
*/
void onNetworkChanged(NetworkInfo networkinfo);
/**
* 当连接服务器成功时回调
* @param hasAutoBind : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当断开服务器连接的时候回调
*
*/
void onConnectionClosed();
/**
* 当连接服务器失败的时候回调
*
*/
void onConnectionFailed();
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
/**
* 当连接服务器成功时回调
*
* @param hasAutoBind
* : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当断开服务器连接的时候回调
*
*/
void onConnectionClosed();
/**
* 当连接服务器失败的时候回调
*
*/
void onConnectionFailed();
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -30,25 +31,23 @@ import com.farsunset.cim.sdk.android.model.SentBody;
import android.net.NetworkInfo;
import android.util.Log;
/**
* CIM 消息监听器管理
*/
public class CIMListenerManager {
public class CIMListenerManager {
private static ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
private static CIMMessageReceiveComparator comparator = new CIMMessageReceiveComparator();
public static void registerMessageListener(CIMEventListener listener) {
if (!cimListeners.contains(listener)) {
cimListeners.add(listener);
Collections.sort(cimListeners,comparator);
Collections.sort(cimListeners, comparator);
}
}
public static void removeMessageListener(CIMEventListener listener) {
for (int i = 0; i < cimListeners.size(); i++) {
if (listener.getClass() == cimListeners.get(i).getClass()) {
@ -56,76 +55,72 @@ public class CIMListenerManager {
}
}
}
public static void notifyOnNetworkChanged(NetworkInfo info) {
for (CIMEventListener listener : cimListeners) {
listener.onNetworkChanged(info);
}
}
public static void notifyOnConnectionSuccessed(boolean hasAutoBind) {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionSuccessed(hasAutoBind);
}
}
public static void notifyOnMessageReceived(Message message) {
for (CIMEventListener listener : cimListeners) {
listener.onMessageReceived(message);
}
}
public static void notifyOnConnectionClosed() {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionClosed();
}
}
public static void notifyOnConnectionFailed() {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionFailed();
}
}
public static void notifyOnReplyReceived(ReplyBody body) {
for (CIMEventListener listener : cimListeners) {
listener.onReplyReceived(body);
}
}
public static void notifyOnSentSucceed(SentBody body) {
for (CIMEventListener listener : cimListeners) {
listener.onSentSuccessed(body);
}
}
public static void destory() {
cimListeners.clear();
}
public static void logListenersName() {
for (CIMEventListener listener : cimListeners) {
Log.i(CIMEventListener.class.getSimpleName(),"#######" + listener.getClass().getName() + "#######" );
Log.i(CIMEventListener.class.getSimpleName(), "#######" + listener.getClass().getName() + "#######");
}
}
/**
* 消息接收activity的接收顺序排序CIM_RECEIVE_ORDER倒序
*/
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener>{
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener> {
@Override
public int compare(CIMEventListener arg1, CIMEventListener arg2) {
int order1 = arg1.getEventDispatchOrder();
int order2 = arg2.getEventDispatchOrder();
return order2 - order1 ;
return order2 - order1;
}
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.util.UUID;
import android.content.Context;
@ -34,212 +35,204 @@ import com.farsunset.cim.sdk.android.model.SentBody;
/**
* CIM 功能接口
*/
public class CIMPushManager {
public class CIMPushManager {
static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY = "ACTION_DESTORY";
static String KEY_SEND_BODY = "KEY_SEND_BODY";
static String KEY_CIM_CONNECTION_STATUS = "KEY_CIM_CONNECTION_STATUS";
static String ACTION_ACTIVATE_PUSH_SERVICE ="ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION ="ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY ="ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION ="ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY ="ACTION_DESTORY";
static String KEY_SEND_BODY ="KEY_SEND_BODY";
static String KEY_CIM_CONNECTION_STATUS ="KEY_CIM_CONNECTION_STATUS";
/**
* 初始化,连接服务端在程序启动页或者 在Application里调用
*
* @param context
* @param ip
* @param port
*/
public static void connect(Context context,String host,int port){
connect(context,host,port,false,0);
}
private static void connect(Context context,String ip,int port,boolean autoBind,long delayedTime){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED, false);
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, false);
public static void connect(Context context, String host, int port) {
connect(context, host, port, false, 0);
}
private static void connect(Context context, String ip, int port, boolean autoBind, long delayedTime) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false);
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
CIMCacheManager.putInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
if(!autoBind)
{
CIMCacheManager.remove(context,CIMCacheManager.KEY_ACCOUNT);
if (!autoBind) {
CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT);
}
Intent serviceIntent = new Intent(context, CIMPushService.class);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delayedTime);
serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION);
context.startService(serviceIntent);
}
protected static void connect(Context context,long delayedTime){
boolean isManualStop = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
}
protected static void connect(Context context, long delayedTime) {
boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
String host = CIMCacheManager.getString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port =CIMCacheManager.getInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT);
connect(context,host,port,true,delayedTime);
}
int port = CIMCacheManager.getInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT);
connect(context, host, port, true, delayedTime);
}
/**
* 设置一个账号登录到服务端
* @param account 用户唯一ID
*
* @param account
* 用户唯一ID
*/
public static void bindAccount(Context context,String account){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory || account==null || account.trim().length()==0)
{
return ;
}
sendBindRequest(context,account);
public static void bindAccount(Context context, String account) {
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory || account == null || account.trim().length() == 0) {
return;
}
sendBindRequest(context, account);
}
private static void sendBindRequest(Context context, String account){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context,CIMCacheManager.KEY_ACCOUNT, account);
String deviceId = CIMCacheManager.getString(context,CIMCacheManager.KEY_DEVICE_ID);
if(TextUtils.isEmpty(deviceId)) {
deviceId = UUID.randomUUID().toString().replaceAll("-", "");
CIMCacheManager.putString(context,CIMCacheManager.KEY_DEVICE_ID, deviceId);
}
SentBody sent = new SentBody();
private static void sendBindRequest(Context context, String account) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, account);
String deviceId = CIMCacheManager.getString(context, CIMCacheManager.KEY_DEVICE_ID);
if (TextUtils.isEmpty(deviceId)) {
deviceId = UUID.randomUUID().toString().replaceAll("-", "");
CIMCacheManager.putString(context, CIMCacheManager.KEY_DEVICE_ID, deviceId);
}
SentBody sent = new SentBody();
sent.setKey(CIMConstant.RequestKey.CLIENT_BIND);
sent.put("account", account);
sent.put("deviceId",deviceId);
sent.put("deviceId", deviceId);
sent.put("channel", "android");
sent.put("device",android.os.Build.MODEL);
sent.put("version",getVersionName(context));
sent.put("osVersion",android.os.Build.VERSION.RELEASE);
sent.put("packageName",context.getPackageName());
sendRequest(context,sent);
}
protected static boolean autoBindAccount(Context context){
String account = CIMCacheManager.getString(context,CIMCacheManager.KEY_ACCOUNT);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if( account==null || account.trim().length()==0 || isManualDestory )
{
return false;
}
sendBindRequest(context,account);
return true;
sent.put("device", android.os.Build.MODEL);
sent.put("version", getVersionName(context));
sent.put("osVersion", android.os.Build.VERSION.RELEASE);
sent.put("packageName", context.getPackageName());
sendRequest(context, sent);
}
protected static boolean autoBindAccount(Context context) {
/**
String account = CIMCacheManager.getString(context, CIMCacheManager.KEY_ACCOUNT);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (account == null || account.trim().length() == 0 || isManualDestory) {
return false;
}
sendBindRequest(context, account);
return true;
}
/**
* 发送一个CIM请求
*
* @param context
* @body
*/
public static void sendRequest(Context context, SentBody body){
boolean isManualStop = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
public static void sendRequest(Context context, SentBody body) {
boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
Intent serviceIntent = new Intent(context, CIMPushService.class);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.putExtra(KEY_SEND_BODY, body);
serviceIntent.setAction(ACTION_SEND_REQUEST_BODY);
context.startService(serviceIntent);
}
/**
/**
* 停止接受推送将会退出当前账号登录端口与服务端的连接
*
* @param context
*/
public static void stop(Context context){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, true);
public static void stop(Context context) {
Intent serviceIntent = new Intent(context, CIMPushService.class);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, true);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION);
context.startService(serviceIntent);
}
/**
/**
* 完全销毁CIM一般用于完全退出程序调用resume将不能恢复
*
* @param context
*/
public static void destroy(Context context){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED, true);
CIMCacheManager.putString(context,CIMCacheManager.KEY_ACCOUNT, null);
Intent serviceIntent = new Intent(context, CIMPushService.class);
public static void destroy(Context context) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, true);
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, null);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.setAction(ACTION_DESTORY);
context.startService(serviceIntent);
}
/**
* 重新恢复接收推送重新连接服务端并登录当前账号
* @param context
*/
public static void resume(Context context){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
autoBindAccount(context);
/**
* 重新恢复接收推送重新连接服务端并登录当前账号
*
* @param context
*/
public static void resume(Context context) {
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
autoBindAccount(context);
}
public static boolean isConnected(Context context){
return CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE);
}
private static String getVersionName(Context context) {
String versionName = null;
public static boolean isConnected(Context context) {
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE);
}
private static String getVersionName(Context context) {
String versionName = null;
try {
PackageInfo mPackageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
versionName = mPackageInfo.versionName;

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
@ -28,98 +29,88 @@ import android.os.Message;
import android.util.Log;
import com.farsunset.cim.sdk.android.model.SentBody;
/**
* 与服务端连接服务
*
* @author 3979434
*
*/
public class CIMPushService extends Service {
private final String TAG = CIMPushService.class.getSimpleName();
public final static String KEY_DELAYED_TIME ="KEY_DELAYED_TIME";
public class CIMPushService extends Service {
private final String TAG = CIMPushService.class.getSimpleName();
public final static String KEY_DELAYED_TIME = "KEY_DELAYED_TIME";
private CIMConnectorManager manager;
@Override
public void onCreate()
{
manager = CIMConnectorManager.getManager(this.getApplicationContext());
}
Handler connectionHandler = new Handler(){
@Override
public void onCreate() {
manager = CIMConnectorManager.getManager(this.getApplicationContext());
}
Handler connectionHandler = new Handler() {
@Override
public void handleMessage(android.os.Message message){
public void handleMessage(android.os.Message message) {
connectionHandler.removeMessages(0);
String host = message.getData().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = message.getData().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT,0);
int port = message.getData().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0);
manager.connect(host, port);
}
};
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if(CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action))
{
long delayMillis = intent.getLongExtra(KEY_DELAYED_TIME,0);
if( delayMillis > 0){
Message msg = connectionHandler.obtainMessage();
msg.what = 0;
msg.setData(intent.getExtras());
connectionHandler.sendMessageDelayed(msg, delayMillis);
}else
{
String host = intent.getStringExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = intent.getIntExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT,0);
manager.connect(host,port);
}
}
if(CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action))
{
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
}
if(CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action))
{
manager.closeSession();
}
if(CIMPushManager.ACTION_DESTORY.equals(action))
{
manager.destroy();
this.stopSelf();
}
if(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action) )
{
if(!manager.isConnected()){
boolean isManualStop = CIMCacheManager.getBoolean(getApplicationContext(),CIMCacheManager.KEY_MANUAL_STOP);
Log.w(TAG, "manager.isConnected() == false, isManualStop == " + isManualStop);
CIMPushManager.connect(this,0);
}else
{
Log.i(TAG, "manager.isConnected() == true");
}
}
return START_STICKY;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) {
long delayMillis = intent.getLongExtra(KEY_DELAYED_TIME, 0);
if (delayMillis > 0) {
Message msg = connectionHandler.obtainMessage();
msg.what = 0;
msg.setData(intent.getExtras());
connectionHandler.sendMessageDelayed(msg, delayMillis);
} else {
String host = intent.getStringExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = intent.getIntExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0);
manager.connect(host, port);
}
}
if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) {
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
}
if (CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action)) {
manager.closeSession();
}
if (CIMPushManager.ACTION_DESTORY.equals(action)) {
manager.destroy();
this.stopSelf();
}
if (CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action)) {
if (!manager.isConnected()) {
boolean isManualStop = CIMCacheManager.getBoolean(getApplicationContext(),
CIMCacheManager.KEY_MANUAL_STOP);
Log.w(TAG, "manager.isConnected() == false, isManualStop == " + isManualStop);
CIMPushManager.connect(this, 0);
} else {
Log.i(TAG, "manager.isConnected() == true");
}
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return null;

View File

@ -21,90 +21,85 @@
*/
package com.farsunset.cim.sdk.android.constant;
/**
/**
* 常量
*/
public interface CIMConstant {
long RECONN_INTERVAL_TIME= 30 * 1000;
//消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
public interface CIMConstant {
long RECONN_INTERVAL_TIME = 30 * 1000;
// 消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
int DATA_HEADER_LENGTH = 3;
public static interface ReturnCode{
String CODE_404 ="404";
String CODE_403 ="403";
String CODE_405 ="405";
String CODE_200 ="200";
String CODE_206 ="206";
String CODE_500 ="500";
public static interface ReturnCode {
String CODE_404 = "404";
String CODE_403 = "403";
String CODE_405 = "405";
String CODE_200 = "200";
String CODE_206 = "206";
String CODE_500 = "500";
}
public static interface ProtobufType {
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey {
String CLIENT_BIND = "client_bind";
String CLIENT_LOGOUT = "client_logout";
public static interface ProtobufType{
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey{
String CLIENT_BIND ="client_bind";
String CLIENT_LOGOUT ="client_logout";
@Deprecated
String CLIENT_PULL_MESSAGE ="client_pull_message";
String CLIENT_PULL_MESSAGE = "client_pull_message";
}
public static interface MessageAction{
//被其他设备登录挤下线消息
String ACTION_999 ="999";
}
public static interface IntentAction{
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
//重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
}
public static interface MessageAction {
// 被其他设备登录挤下线消息
String ACTION_999 = "999";
}
public static interface IntentAction {
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
// 重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
}
}

View File

@ -23,14 +23,14 @@ package com.farsunset.cim.sdk.android.exception;
import java.io.Serializable;
public class NetworkDisabledException extends Exception implements Serializable {
public class NetworkDisabledException extends Exception implements Serializable {
private static final long serialVersionUID = 1L;
public NetworkDisabledException() {
super();
}
public NetworkDisabledException(String s) {
super(s);
}

View File

@ -24,7 +24,7 @@ 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() {

View File

@ -26,7 +26,7 @@ import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
/**
/**
* android客户端端消息 编码解码器
*/
public class ClientMessageCodecFactory implements ProtocolCodecFactory {
@ -34,23 +34,23 @@ public class ClientMessageCodecFactory implements ProtocolCodecFactory {
/**
* 消息编码器
*/
private final ClientMessageEncoder encoder;
/**
private final ClientMessageEncoder encoder;
/**
* 消息解码器
*/
private final ClientMessageDecoder decoder;
private final ClientMessageDecoder decoder;
public ClientMessageCodecFactory() {
encoder = new ClientMessageEncoder();
decoder = new ClientMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
public ClientMessageCodecFactory() {
encoder = new ClientMessageEncoder();
decoder = new ClientMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.android.filter;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
@ -35,79 +34,73 @@ import com.farsunset.cim.sdk.android.model.ReplyBody;
import com.farsunset.cim.sdk.android.model.proto.MessageProto;
import com.farsunset.cim.sdk.android.model.proto.ReplyBodyProto;
import com.google.protobuf.InvalidProtocolBufferException;
/**
* 客户端消息解码
* 客户端消息解码
*/
public class ClientMessageDecoder extends CumulativeProtocolDecoder {
final static String TAG = ClientMessageDecoder.class.getSimpleName();
@Override
public boolean doDecode(IoSession iosession, IoBuffer iobuffer,
ProtocolDecoderOutput out) throws Exception {
public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
/**
* 消息头3位
*/
if (iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH) {
return false;
}
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv = iobuffer.get();// int 低位
byte hv = iobuffer.get();// int 高位
int conetnLength = getContentLength(lv, hv);
// 如果消息体没有接收完整则重置读取等待下一次重新读取
if (conetnLength > iobuffer.remaining()) {
iobuffer.reset();
return false;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes, conetnType);
if (message != null) {
out.write(message);
}
/**
* 消息头3位
*/
if(iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH){
return false;
}
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv =iobuffer.get();//int 低位
byte hv =iobuffer.get();//int 高位
int conetnLength = getContentLength(lv,hv);
//如果消息体没有接收完整则重置读取等待下一次重新读取
if(conetnLength > iobuffer.remaining()){
iobuffer.reset();
return false;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes,conetnType);
if(message!=null){
out.write(message);
}
return true;
}
private Object mappingMessageObject(byte[] bytes,byte type) throws InvalidProtocolBufferException {
if(CIMConstant.ProtobufType.S_H_RQ == type)
{
private Object mappingMessageObject(byte[] bytes, byte type) throws InvalidProtocolBufferException {
if (CIMConstant.ProtobufType.S_H_RQ == type) {
HeartbeatRequest request = HeartbeatRequest.getInstance();
Log.i(TAG,request.toString());
Log.i(TAG, request.toString());
return request;
}
if(CIMConstant.ProtobufType.REPLYBODY == type)
{
if (CIMConstant.ProtobufType.REPLYBODY == type) {
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bytes);
ReplyBody body = new ReplyBody();
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
body.setCode(bodyProto.getCode());
body.setMessage(bodyProto.getMessage());
Log.i(TAG,body.toString());
return body;
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
body.setCode(bodyProto.getCode());
body.setMessage(bodyProto.getMessage());
Log.i(TAG, body.toString());
return body;
}
if(CIMConstant.ProtobufType.MESSAGE == type)
{
if (CIMConstant.ProtobufType.MESSAGE == type) {
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bytes);
Message message = new Message();
message.setMid(bodyProto.getMid());
@ -119,25 +112,26 @@ public class ClientMessageDecoder extends CumulativeProtocolDecoder {
message.setExtra(bodyProto.getExtra());
message.setTimestamp(bodyProto.getTimestamp());
message.setFormat(bodyProto.getFormat());
Log.i(TAG,message.toString());
return message;
Log.i(TAG, message.toString());
return message;
}
return null;
}
/**
/**
* 解析消息体长度
*
* @param type
* @param length
* @return
*/
private int getContentLength(byte lv,byte hv){
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l| (h <<= 8));
private int getContentLength(byte lv, byte hv) {
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l | (h <<= 8));
}
}

View File

@ -29,45 +29,48 @@ import android.util.Log;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
import com.farsunset.cim.sdk.android.model.Protobufable;
/**
* 客户端消息发送前进行编码
* 客户端消息发送前进行编码
*/
public class ClientMessageEncoder extends ProtocolEncoderAdapter {
final static String TAG = ClientMessageEncoder.class.getSimpleName();
@Override
public void encode(IoSession iosession, Object object, ProtocolEncoderOutput out) throws Exception {
if(object instanceof Protobufable){
Protobufable data = (Protobufable) object;
byte[] byteArray = data.getByteArray();
IoBuffer buff = IoBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH).setAutoExpand(true);
buff.put(createHeader(data.getType(),byteArray.length));
buff.put(byteArray);
buff.flip();
if (object instanceof Protobufable) {
Protobufable data = (Protobufable) object;
byte[] byteArray = data.getByteArray();
IoBuffer buff = IoBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH).setAutoExpand(true);
buff.put(createHeader(data.getType(), byteArray.length));
buff.put(byteArray);
buff.flip();
out.write(buff);
//打印出收到的消息
Log.i(TAG,data.toString());
}
// 打印出收到的消息
Log.i(TAG, data.toString());
}
}
/**
* 消息体最大为65535
*
* @param type
* @param length
* @return
*/
private byte[] createHeader(byte type,int length){
private byte[] createHeader(byte type, int length) {
byte[] header = new byte[CIMConstant.DATA_HEADER_LENGTH];
header[0] = type;
header[1] = (byte) (length & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
return header;
}
}

View File

@ -24,39 +24,39 @@ package com.farsunset.cim.sdk.android.model;
import java.io.Serializable;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
/**
* 服务端心跳请求
*
*/
public class HeartbeatRequest implements Serializable,Protobufable {
public class HeartbeatRequest implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
private static final String CMD_HEARTBEAT_REQUEST = "SR";
private static HeartbeatRequest object = new HeartbeatRequest();
private HeartbeatRequest(){
private HeartbeatRequest() {
}
public static HeartbeatRequest getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_REQUEST.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@Override
public byte getType() {
return CIMConstant.ProtobufType.S_H_RQ;
}
}

View File

@ -24,30 +24,32 @@ package com.farsunset.cim.sdk.android.model;
import java.io.Serializable;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
/**
* 客户端心跳响应
*/
public class HeartbeatResponse implements Serializable,Protobufable {
public class HeartbeatResponse implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse(){
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse() {
}
public static HeartbeatResponse getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@ -55,5 +57,5 @@ public class HeartbeatResponse implements Serializable,Protobufable {
public byte getType() {
return CIMConstant.ProtobufType.C_H_RS;
}
}

View File

@ -30,13 +30,11 @@ public class Message implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 消息类型用户自定义消息类别
*/
private String mid;
/**
* 消息类型用户自定义消息类别
*/
@ -59,8 +57,6 @@ public class Message implements Serializable {
*/
private String receiver;
/**
* content 内容格式
*/
@ -72,12 +68,11 @@ public class Message implements Serializable {
private String extra;
private long timestamp;
public Message()
{
public Message() {
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -86,14 +81,14 @@ public class Message implements Serializable {
this.timestamp = timestamp;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTitle() {
return title;
}
@ -126,7 +121,6 @@ public class Message implements Serializable {
this.receiver = receiver;
}
public String getFormat() {
return format;
}
@ -134,17 +128,17 @@ public class Message implements Serializable {
public void setFormat(String format) {
this.format = format;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#Message#").append("\n");
buffer.append("mid:").append(mid).append("\n");
@ -158,7 +152,6 @@ public class Message implements Serializable {
buffer.append("timestamp:").append(timestamp);
return buffer.toString();
}
public String getMid() {
return mid;
@ -169,8 +162,7 @@ public class Message implements Serializable {
}
public boolean isNotEmpty(String txt) {
return txt != null && txt.trim().length()!=0;
return txt != null && txt.trim().length() != 0;
}
}

View File

@ -20,12 +20,13 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android.model;
/**
* 需要向另一端发送的结构体
*/
public interface Protobufable {
byte[] getByteArray();
byte getType();
}

View File

@ -31,35 +31,31 @@ import java.util.Set;
*
*/
public class ReplyBody implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 请求key
*/
private String key;
/**
* 返回码
*/
private String code;
/**
* 返回说明
*/
private String message;
private long timestamp;
/**
* 返回数据集合
*/
private Hashtable<String, String> data = new Hashtable<String, String>();
public long getTimestamp() {
return timestamp;
}
@ -68,8 +64,6 @@ public class ReplyBody implements Serializable {
this.timestamp = timestamp;
}
public String getKey() {
return key;
}
@ -101,8 +95,8 @@ public class ReplyBody implements Serializable {
public void putAll(Map<String, String> map) {
data.putAll(map);
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
@ -114,24 +108,21 @@ public class ReplyBody implements Serializable {
this.code = code;
}
public String toString()
{
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#ReplyBody#").append("\n");
buffer.append("key:").append(this.getKey()).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
buffer.append("code:").append(code).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}

View File

@ -32,13 +32,13 @@ import com.farsunset.cim.sdk.android.model.proto.SentBodyProto;
* java |android 客户端请求结构
*
*/
public class SentBody implements Serializable,Protobufable {
public class SentBody implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private String key;
private Hashtable<String, String> data = new Hashtable<String, String>();;
private Hashtable<String, String> data = new Hashtable<String, String>();;
private long timestamp;
@ -67,18 +67,16 @@ public class SentBody implements Serializable,Protobufable {
}
public void put(String k, String v) {
if(k == null || v == null){
if (k == null || v == null) {
return;
}
data.put(k, v);
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
public void remove(String k) {
data.remove(k);
}
@ -86,34 +84,34 @@ public class SentBody implements Serializable,Protobufable {
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#SentBody#").append("\n");;
buffer.append("#SentBody#").append("\n");
;
buffer.append("key:").append(key).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}
@Override
public byte[] getByteArray() {
SentBodyProto.Model.Builder builder = SentBodyProto.Model.newBuilder();
builder.setKey(key);
builder.setTimestamp(timestamp);
if(!data.isEmpty()){
if (!data.isEmpty()) {
builder.putAllData(data);
}
return builder.build().toByteArray();
}
@Override
public byte getType() {
return CIMConstant.ProtobufType.SENTBODY;
}
}

View File

@ -23,69 +23,58 @@ package com.farsunset.cim.sdk.client;
import java.util.HashMap;
class CIMCacheToolkit {
class CIMCacheManager {
private static HashMap<String, String> CIM_CONFIG_INFO = new HashMap<String, String>();
private static HashMap<String,String> CIM_CONFIG_INFO = new HashMap<String,String>();
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
public static final String KEY_CIM_SERVIER_HOST = "KEY_CIM_SERVIER_HOST";
public static final String KEY_CIM_SERVIER_PORT = "KEY_CIM_SERVIER_PORT";
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
static CIMCacheToolkit toolkit;
public static CIMCacheToolkit getInstance(){
if (toolkit==null){
toolkit = new CIMCacheToolkit();
}
static CIMCacheManager toolkit;
public static CIMCacheManager getInstance() {
if (toolkit == null) {
toolkit = new CIMCacheManager();
}
return toolkit;
}
public void remove(String key)
{
public void remove(String key) {
CIM_CONFIG_INFO.remove(key);
}
public void putString(String key,String value)
{
CIM_CONFIG_INFO.put(key,value);
public void putString(String key, String value) {
CIM_CONFIG_INFO.put(key, value);
}
public String getString(String key)
{
public String getString(String key) {
return CIM_CONFIG_INFO.get(key);
}
public void putBoolean(String key,boolean value)
{
putString(key,Boolean.toString(value));
public void putBoolean(String key, boolean value) {
putString(key, Boolean.toString(value));
}
public boolean getBoolean(String key)
{
public boolean getBoolean(String key) {
String value = getString(key);
return value == null?false:Boolean.parseBoolean(value);
return value == null ? false : Boolean.parseBoolean(value);
}
public void putInt(String key,int value)
{
public void putInt(String key, int value) {
putString(key, String.valueOf(value));
}
public int getInt(String key)
{
public int getInt(String key) {
String value = getString(key);
return value == null?0:Integer.parseInt(value);
return value == null ? 0 : Integer.parseInt(value);
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.client;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Random;
@ -46,31 +47,28 @@ import com.farsunset.cim.sdk.client.model.Intent;
import com.farsunset.cim.sdk.client.model.Message;
import com.farsunset.cim.sdk.client.model.ReplyBody;
import com.farsunset.cim.sdk.client.model.SentBody;
/**
* 连接服务端管理cim核心处理类管理连接以及消息处理
*
* @author 3979434@qq.com
*/
class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageFactory {
class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageFactory {
protected final Logger logger = Logger.getLogger(CIMConnectorManager.class);
private final int READ_BUFFER_SIZE = 2048;//bit
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int READ_BUFFER_SIZE = 2048;// bit
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int READ_IDLE_TIME = 120;//
private final int READ_IDLE_TIME = 120;//
private final int HEARBEAT_TIME_OUT = (READ_IDLE_TIME + 20) * 1000;// 收到服务端心跳请求超时时间 毫秒
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME" ;
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME";
private NioSocketConnector connector;
private ConnectFuture connectFuture;
private ExecutorService executor = Executors.newFixedThreadPool(1);
private static CIMConnectorManager manager;
private static CIMConnectorManager manager;
private CIMConnectorManager() {
connector = new NioSocketConnector();
@ -78,15 +76,15 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
connector.getSessionConfig().setTcpNoDelay(true);
connector.getSessionConfig().setKeepAlive(true);
connector.getSessionConfig().setReadBufferSize(READ_BUFFER_SIZE);
KeepAliveFilter keepAliveaHandler = new KeepAliveFilter(this);
keepAliveaHandler.setRequestInterval(READ_IDLE_TIME);
keepAliveaHandler.setRequestTimeoutHandler(KeepAliveRequestTimeoutHandler.NOOP);
keepAliveaHandler.setForwardEvent(true);
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ClientMessageCodecFactory()));
connector.getFilterChain().addLast("heartbeat", keepAliveaHandler);
connector.setHandler(this);
}
@ -99,75 +97,74 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
}
private synchronized void syncConnection(final String host,final int port) {
if(isConnected()){
return ;
private synchronized void syncConnection(final String host, final int port) {
if (isConnected()) {
return;
}
try {
logger.info("****************CIM正在连接服务器 "+host+":"+port+"......");
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_CIM_CONNECTION_STATE, false);
logger.info("****************CIM正在连接服务器 " + host + ":" + port + "......");
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
InetSocketAddress remoteSocketAddress = new InetSocketAddress(host, port);
connectFuture = connector.connect(remoteSocketAddress);
connectFuture.awaitUninterruptibly();
connectFuture.getSession();
} catch (Exception e) {
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5*1000 - new Random().nextInt(15*1000));
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5 * 1000 - new Random().nextInt(15 * 1000));
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED);
intent.putExtra(Exception.class.getName(), e);
intent.putExtra("interval", interval);
sendBroadcast(intent);
logger.error("****************CIM连接服务器失败 "+host+":"+port+"......将在"+interval/1000+"秒后重新尝试连接");
}
logger.error(
"****************CIM连接服务器失败 " + host + ":" + port + "......将在" + interval / 1000 + "秒后重新尝试连接");
}
}
public void connect(final String host, final int port) {
executor.execute(new Runnable() {
public void run()
{
public void run() {
syncConnection(host, port);
}
}
});
}
public synchronized void send(SentBody body) {
boolean isSuccessed = false;
Throwable exception = new SessionDisconnectedException();
IoSession session = getCurrentSession();
if(session!=null && session.isConnected())
{
if (session != null && session.isConnected()) {
WriteFuture wf = session.write(body);
// 消息发送超时 5秒
wf.awaitUninterruptibly(WRITE_TIMEOUT);
isSuccessed = wf.isWritten();
exception = wf.getException();
}
if(!isSuccessed){
}
if (!isSuccessed) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_FAILED);
intent.putExtra(Exception.class.getName(),exception);
intent.putExtra(Exception.class.getName(), exception);
intent.putExtra(SentBody.class.getName(), body);
sendBroadcast(intent);
}
}
public void destroy() {
public void destroy() {
IoSession session = getCurrentSession();
if (session != null) {
session.closeNow();
@ -176,59 +173,51 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
if (connector != null && !connector.isDisposed()) {
connector.dispose();
}
manager = null;
}
public boolean isConnected() {
IoSession session = getCurrentSession();
return session != null ;
return session != null;
}
public void closeSession()
{
public void closeSession() {
IoSession session = getCurrentSession();
if(session!=null)
{
if (session != null) {
session.closeNow();
}
}
public IoSession getCurrentSession()
{
Map<Long,IoSession> sessions = connector.getManagedSessions();
for(Long key:sessions.keySet())
{
public IoSession getCurrentSession() {
Map<Long, IoSession> sessions = connector.getManagedSessions();
for (Long key : sessions.keySet()) {
IoSession session = sessions.get(key);
if(session.isConnected()){
if (session.isConnected()) {
return session;
}
}
return null;
}
@Override
public void sessionCreated(IoSession session) throws Exception {
logger.info("****************CIM连接服务器成功:"+session.getLocalAddress()+" NID:"+session.getId());
logger.info("****************CIM连接服务器成功:" + session.getLocalAddress() + " NID:" + session.getId());
setLastHeartbeatTime(session);
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED);
sendBroadcast(intent);
}
@Override
public void sessionClosed(IoSession session) {
logger.error("****************CIM与服务器断开连接:"+session.getLocalAddress()+" NID:"+session.getId());
logger.error("****************CIM与服务器断开连接:" + session.getLocalAddress() + " NID:" + session.getId());
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
sendBroadcast(intent);
@ -236,31 +225,30 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
logger.debug("****************CIM "+status.toString().toUpperCase()+":"+session.getLocalAddress() +" NID:"+session.getId()+ " isConnected:" + session.isConnected());
public void sessionIdle(IoSession session, IdleStatus status) {
logger.debug("****************CIM " + status.toString().toUpperCase() + ":" + session.getLocalAddress()
+ " NID:" + session.getId() + " isConnected:" + session.isConnected());
/**
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件
* 导致这样的情况下当前连接无效也不会重连的问题
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
*
*/
long lastHeartbeatTime = getLastHeartbeatTime(session);
if(System.currentTimeMillis() - lastHeartbeatTime >= HEARBEAT_TIME_OUT)
{
if (System.currentTimeMillis() - lastHeartbeatTime >= HEARBEAT_TIME_OUT) {
session.closeNow();
logger.error("****************CIM心跳超时 ,即将重新连接......"+" NID:"+session.getId());
logger.error("****************CIM心跳超时 ,即将重新连接......" + " NID:" + session.getId());
}
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
logger.error("****************CIM连接出现未知异常:"+session.getLocalAddress()+" NID:"+session.getId());
if(cause!=null && cause.getMessage()!=null){
logger.error("****************CIM连接出现未知异常:" + session.getLocalAddress() + " NID:" + session.getId());
if (cause != null && cause.getMessage() != null) {
logger.error(cause.getMessage());
}
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_UNCAUGHT_EXCEPTION);
intent.putExtra(Exception.class.getName(), cause);
@ -268,18 +256,18 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
}
@Override
public void messageReceived(IoSession session, Object obj){
public void messageReceived(IoSession session, Object obj) {
if (obj instanceof Message) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
intent.putExtra(Message.class.getName(), (Message) obj);
sendBroadcast(intent);
}
if (obj instanceof ReplyBody) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
@ -289,32 +277,27 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
@Override
public void messageSent(IoSession session, Object message) {
if(message instanceof SentBody)
{
if (message instanceof SentBody) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED);
intent.putExtra(SentBody.class.getName(), (SentBody) message);
sendBroadcast(intent);
}
}
private void setLastHeartbeatTime(IoSession session)
{
private void setLastHeartbeatTime(IoSession session) {
session.setAttribute(KEY_LAST_HEART_TIME, System.currentTimeMillis());
}
private long getLastHeartbeatTime(IoSession session)
{
private long getLastHeartbeatTime(IoSession session) {
long time = 0;
Object value = session.getAttribute(KEY_LAST_HEART_TIME);
if(value !=null){
if (value != null) {
time = Long.parseLong(value.toString());
}
return time;
}
@Override
public Object getRequest(IoSession arg0) {
return null;
@ -327,9 +310,9 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
@Override
public boolean isRequest(IoSession session, Object data) {
setLastHeartbeatTime(session);
return data instanceof HeartbeatRequest;
}
@ -337,13 +320,13 @@ class CIMConnectorManager extends IoHandlerAdapter implements KeepAliveMessageF
public boolean isResponse(IoSession arg0, Object arg1) {
return false;
}
private void sendBroadcast(final Intent intent) {
executor.execute(new Runnable(){
@Override
public void run() {
CIMEventBroadcastReceiver.getInstance().onReceive(intent);
}
executor.execute(new Runnable() {
@Override
public void run() {
CIMEventBroadcastReceiver.getInstance().onReceive(intent);
}
});
}
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.client;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
@ -32,171 +31,155 @@ import com.farsunset.cim.sdk.client.model.Intent;
import com.farsunset.cim.sdk.client.model.Message;
import com.farsunset.cim.sdk.client.model.ReplyBody;
import com.farsunset.cim.sdk.client.model.SentBody;
/**
* 消息入口所有消息都会经过这里
* 消息入口所有消息都会经过这里
*/
public class CIMEventBroadcastReceiver {
Random random = new Random();
public class CIMEventBroadcastReceiver {
Random random = new Random();
private static CIMEventBroadcastReceiver recerver;
private CIMEventListener listener;
private Timer connectionHandler = new Timer();;
public static CIMEventBroadcastReceiver getInstance(){
if (recerver==null){
recerver = new CIMEventBroadcastReceiver();
}
public static CIMEventBroadcastReceiver getInstance() {
if (recerver == null) {
recerver = new CIMEventBroadcastReceiver();
}
return recerver;
}
public void setGlobalCIMEventListener(CIMEventListener ls){
public void setGlobalCIMEventListener(CIMEventListener ls) {
listener = ls;
}
public void onReceive(Intent intent) {
/*
* cim断开服务器事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED))
{
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED))
{
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
onInnerConnectionFailed((Exception) intent.getExtra(Exception.class.getName()),interval);
}
/*
* cim连接服务器成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED))
{
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED))
{
onInnerMessageReceived((Message)intent.getExtra(Message.class.getName()));
}
/*
* 获取收到replybody成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED))
{
listener.onReplyReceived((ReplyBody)intent.getExtra(ReplyBody.class.getName()));
}
/*
* 获取sendbody发送失败事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_FAILED))
{
onSentFailed((Exception) intent.getExtra(Exception.class.getName()),(SentBody)intent.getExtra(SentBody.class.getName()));
}
/*
* 获取sendbody发送成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED))
{
onSentSucceed((SentBody)intent.getExtra(SentBody.class.getName()));
}
/*
* 获取cim数据传输异常事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_UNCAUGHT_EXCEPTION))
{
onUncaughtException((Exception)intent.getExtra(Exception.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY))
{
CIMPushManager.connect();
}
/*
* cim断开服务器事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED)) {
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED)) {
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
onInnerConnectionFailed((Exception) intent.getExtra(Exception.class.getName()), interval);
}
/*
* cim连接服务器成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED)) {
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED)) {
onInnerMessageReceived((Message) intent.getExtra(Message.class.getName()));
}
/*
* 获取收到replybody成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED)) {
listener.onReplyReceived((ReplyBody) intent.getExtra(ReplyBody.class.getName()));
}
/*
* 获取sendbody发送失败事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_FAILED)) {
onSentFailed((Exception) intent.getExtra(Exception.class.getName()),
(SentBody) intent.getExtra(SentBody.class.getName()));
}
/*
* 获取sendbody发送成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED)) {
onSentSucceed((SentBody) intent.getExtra(SentBody.class.getName()));
}
/*
* 获取cim数据传输异常事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_UNCAUGHT_EXCEPTION)) {
onUncaughtException((Exception) intent.getExtra(Exception.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY)) {
CIMPushManager.connect();
}
}
private void onInnerConnectionClosed(){
private void onInnerConnectionClosed() {
listener.onConnectionClosed();
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_CIM_CONNECTION_STATE, false);
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
CIMPushManager.connect();
}
private void onInnerConnectionFailed(Exception e,long interval){
connectionHandler.schedule(new ConnectionTask(),interval);
listener.onConnectionFailed(e);
private void onInnerConnectionFailed(Exception e, long interval) {
connectionHandler.schedule(new ConnectionTask(), interval);
listener.onConnectionFailed(e);
}
private void onInnerConnectionSuccessed(){
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_CIM_CONNECTION_STATE, true);
boolean autoBind = CIMPushManager.autoBindDeviceId();
private void onInnerConnectionSuccessed() {
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
boolean autoBind = CIMPushManager.autoBindDeviceId();
listener.onConnectionSuccessed(autoBind);
}
private void onUncaughtException(Throwable arg0) {}
private void onUncaughtException(Throwable arg0) {
}
private void onInnerMessageReceived(com.farsunset.cim.sdk.client.model.Message message) {
if (isForceOfflineMessage(message.getAction())) {
CIMPushManager.stop();
}
private void onInnerMessageReceived(com.farsunset.cim.sdk.client.model.Message message)
{
listener.onMessageReceived(message);
}
private void onSentFailed(Exception e, SentBody body){
e.printStackTrace();
//与服务端端开链接重新连接
if(e instanceof SessionDisconnectedException)
{
CIMPushManager.connect();
}else
{
//发送失败 重新发送
//CIMPushManager.sendRequest( body);
}
private boolean isForceOfflineMessage(String action) {
return CIMConstant.MessageAction.ACTION_999.equals(action);
}
private void onSentSucceed(SentBody body){}
class ConnectionTask extends TimerTask{
public void run(){
private void onSentFailed(Exception e, SentBody body) {
e.printStackTrace();
// 与服务端端开链接重新连接
if (e instanceof SessionDisconnectedException) {
CIMPushManager.connect();
} else {
// 发送失败 重新发送
CIMPushManager.sendRequest(body);
}
}
private void onSentSucceed(SentBody body) {
}
class ConnectionTask extends TimerTask {
public void run() {
CIMPushManager.connect();
}
}
}

View File

@ -21,50 +21,49 @@
*/
package com.farsunset.cim.sdk.client;
import com.farsunset.cim.sdk.client.model.Message;
import com.farsunset.cim.sdk.client.model.ReplyBody;
/**
*CIM 主要事件接口
* CIM 主要事件接口
*/
public interface CIMEventListener
{
public interface CIMEventListener {
/**
* 当收到服务端推送过来的消息时调用
*
* @param message
*/
void onMessageReceived(Message message);
/**
* 当收到服务端推送过来的消息时调用
* @param message
*/
void onMessageReceived(Message message);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
*
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当连接服务器成功时回调
*
* @param hasAutoBind
* : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当连接服务器成功时回调
* @param hasAutoBind : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当断开服务器连接的时候回调
*/
void onConnectionClosed();
/**
* 当服务器连接失败的时候回调
*
*/
void onConnectionFailed(Exception e);
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
/**
* 当断开服务器连接的时候回调
*/
void onConnectionClosed();
/**
* 当服务器连接失败的时候回调
*
*/
void onConnectionFailed(Exception e);
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -29,26 +30,23 @@ import org.apache.log4j.Logger;
import com.farsunset.cim.sdk.client.model.Message;
import com.farsunset.cim.sdk.client.model.ReplyBody;
/**
* CIM 消息监听器管理
*/
public class CIMListenerManager {
public class CIMListenerManager {
private static ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
private static CIMMessageReceiveComparator comparator = new CIMMessageReceiveComparator();
protected static final Logger logger = Logger.getLogger(CIMListenerManager.class);
public static void registerMessageListener(CIMEventListener listener) {
if (!cimListeners.contains(listener)) {
cimListeners.add(listener);
Collections.sort(cimListeners,comparator);
Collections.sort(cimListeners, comparator);
}
}
public static void removeMessageListener(CIMEventListener listener) {
for (int i = 0; i < cimListeners.size(); i++) {
if (listener.getClass() == cimListeners.get(i).getClass()) {
@ -56,61 +54,60 @@ public class CIMListenerManager {
}
}
}
public static void notifyOnConnectionSuccessed(boolean antoBind) {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionSuccessed(antoBind);
}
}
public static void notifyOnMessageReceived(Message message) {
for (CIMEventListener listener : cimListeners) {
listener.onMessageReceived(message);
}
}
public static void notifyOnConnectionClosed() {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionClosed();
}
}
public static void notifyOnReplyReceived(ReplyBody body) {
for (CIMEventListener listener : cimListeners) {
listener.onReplyReceived(body);
}
}
public static void notifyOnConnectionFailed(Exception e) {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionFailed(e);
}
}
public static void destory() {
cimListeners.clear();
}
public static void logListenersName() {
for (CIMEventListener listener : cimListeners) {
logger.debug("#######" + listener.getClass().getName() + "#######" );
logger.debug("#######" + listener.getClass().getName() + "#######");
}
}
/**
* 消息接收activity的接收顺序排序CIM_RECEIVE_ORDER倒序
*/
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener>{
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener> {
@Override
public int compare(CIMEventListener arg1, CIMEventListener arg2) {
int order1 = arg1.getEventDispatchOrder();
int order2 = arg2.getEventDispatchOrder();
return order2 - order1 ;
return order2 - order1;
}
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.client;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Properties;
@ -33,254 +34,246 @@ import com.farsunset.cim.sdk.client.model.SentBody;
/**
* CIM 功能接口
*/
public class CIMPushManager {
public class CIMPushManager {
protected static final Logger logger = Logger.getLogger(CIMPushManager.class);
static String ACTION_ACTIVATE_PUSH_SERVICE ="ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION ="ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY ="ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION ="ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY ="ACTION_DESTORY";
static String KEY_CIM_CONNECTION_STATUS ="KEY_CIM_CONNECTION_STATUS";
//被销毁的destroy()
static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY = "ACTION_DESTORY";
static String KEY_CIM_CONNECTION_STATUS = "KEY_CIM_CONNECTION_STATUS";
// 被销毁的destroy()
public static final int STATE_DESTROYED = 0x0000DE;
//被销停止的 stop()
// 被销停止的 stop()
public static final int STATE_STOPED = 0x0000EE;
public static final int STATE_NORMAL = 0x000000;
/**
* 初始化,连接服务端在程序启动页或者 在Application里调用
*
* @param context
* @param ip
* @param port
*/
public static void connect(String ip,int port){
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED, false);
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_MANUAL_STOP, false);
CIMCacheToolkit.getInstance().putString( CIMCacheToolkit.KEY_CIM_SERVIER_HOST, ip);
CIMCacheToolkit.getInstance().putInt( CIMCacheToolkit.KEY_CIM_SERVIER_PORT, port);
Intent serviceIntent = new Intent();
serviceIntent.putExtra(CIMCacheToolkit.KEY_CIM_SERVIER_HOST, ip);
serviceIntent.putExtra(CIMCacheToolkit.KEY_CIM_SERVIER_PORT, port);
public static void connect(String ip, int port) {
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_CIM_DESTROYED, false);
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.getInstance().putString(CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
CIMCacheManager.getInstance().putInt(CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
Intent serviceIntent = new Intent();
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION);
startService(serviceIntent);
}
private static void startService(Intent intent) {
CIMPushService.getInstance().onStartCommand(intent);
}
protected static void connect(){
boolean isManualStop = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
}
String host = CIMCacheToolkit.getInstance().getString( CIMCacheToolkit.KEY_CIM_SERVIER_HOST);
int port =CIMCacheToolkit.getInstance().getInt( CIMCacheToolkit.KEY_CIM_SERVIER_PORT);
connect(host,port);
}
private static void sendBindRequest(String account){
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_MANUAL_STOP, false);
SentBody sent = new SentBody();
Properties sysPro=System.getProperties();
protected static void connect() {
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
String host = CIMCacheManager.getInstance().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = CIMCacheManager.getInstance().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT);
connect(host, port);
}
private static void sendBindRequest(String account) {
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_MANUAL_STOP, false);
SentBody sent = new SentBody();
Properties sysPro = System.getProperties();
sent.setKey(CIMConstant.RequestKey.CLIENT_BIND);
sent.put("account", account);
sent.put("deviceId", getLocalMac());
sent.put("channel", sysPro.getProperty("os.name"));
sent.put("device",getDeviceModel());
sent.put("version",getClientVersion());
sent.put("osVersion",sysPro.getProperty("os.version"));
sent.put("device", getDeviceModel());
sent.put("version", getClientVersion());
sent.put("osVersion", sysPro.getProperty("os.version"));
sendRequest(sent);
}
/**
}
/**
* 设置一个账号登录到服务端
* @param account 用户唯一ID
*
* @param account
* 用户唯一ID
*/
public static void bindAccount(String account){
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualDestory || account==null || account.trim().length()==0)
{
return ;
}
sendBindRequest(account);
}
protected static boolean autoBindDeviceId(){
String account = getAccount();
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
boolean isManualStoped = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_MANUAL_STOP);
if( isManualStoped || account==null || account.trim().length()==0 || isManualDestory )
{
return false;
}
sendBindRequest(account);
return true;
public static void bindAccount(String account) {
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory || account == null || account.trim().length() == 0) {
return;
}
sendBindRequest(account);
}
protected static boolean autoBindDeviceId() {
/**
String account = getAccount();
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
boolean isManualStoped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
if (isManualStoped || account == null || account.trim().length() == 0 || isManualDestory) {
return false;
}
sendBindRequest(account);
return true;
}
/**
* 发送一个CIM请求
*
* @param context
* @body
*/
public static void sendRequest(SentBody body){
boolean isManualStop = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
public static void sendRequest(SentBody body) {
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
Intent serviceIntent = new Intent();
Intent serviceIntent = new Intent();
serviceIntent.putExtra(SentBody.class.getName(), body);
serviceIntent.setAction(ACTION_SEND_REQUEST_BODY);
startService(serviceIntent);
}
/**
* 停止接受推送将会退出当前账号登录端口与服务端的连接
* @param context
*/
public static void stop(){
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_MANUAL_STOP, true);
Intent serviceIntent = new Intent();
serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION);
startService(serviceIntent);
}
/**
* 完全销毁CIM一般用于完全退出程序调用resume将不能恢复
/**
* 停止接受推送将会退出当前账号登录端口与服务端的连接
*
* @param context
*/
public static void destroy(){
CIMCacheToolkit.getInstance().putBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED, true);
Intent serviceIntent = new Intent();
public static void stop() {
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_MANUAL_STOP, true);
startService(new Intent(ACTION_CLOSE_CIM_CONNECTION));
}
/**
* 完全销毁CIM一般用于完全退出程序调用resume将不能恢复
*
* @param context
*/
public static void destroy() {
CIMCacheManager.getInstance().putBoolean(CIMCacheManager.KEY_CIM_DESTROYED, true);
Intent serviceIntent = new Intent();
serviceIntent.setAction(ACTION_DESTORY);
startService(serviceIntent);
}
/**
* 重新恢复接收推送重新连接服务端并登录当前账号如果aotuBind == true
* @param context
* @param aotuBind
*/
public static void resume(){
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
autoBindDeviceId();
/**
* 重新恢复接收推送重新连接服务端并登录当前账号如果aotuBind == true
*
* @param context
* @param aotuBind
*/
public static void resume() {
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
autoBindDeviceId();
}
public static boolean isConnected(){
return CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_CONNECTION_STATE);
}
public static int getState(){
boolean isManualDestory = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_CIM_DESTROYED);
if(isManualDestory){
public static boolean isConnected() {
return CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_CONNECTION_STATE);
}
public static int getState() {
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return STATE_DESTROYED;
}
boolean isManualStop = CIMCacheToolkit.getInstance().getBoolean(CIMCacheToolkit.KEY_MANUAL_STOP);
if(isManualStop){
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
if (isManualStop) {
return STATE_STOPED;
}
return STATE_NORMAL;
}
public static String getDeviceModel(){
return System.getProperties().getProperty(CIMConstant.ConfigKey.DEVICE_MODEL);
}
public static String getClientVersion(){
return System.getProperties().getProperty(CIMConstant.ConfigKey.CLIENT_VERSION);
}
public static String getAccount(){
return System.getProperties().getProperty(CIMConstant.ConfigKey.CLIENT_ACCOUNT);
}
public static void setAccount(String account){
System.getProperties().put(CIMConstant.ConfigKey.CLIENT_ACCOUNT,account);
}
public static void setClientVersion(String version){
System.getProperties().put(CIMConstant.ConfigKey.CLIENT_VERSION,version);
}
public static void setDeviceModel(String model){
System.getProperties().put(CIMConstant.ConfigKey.DEVICE_MODEL,model);
}
private static String getLocalMac() {
InetAddress ia;
return STATE_NORMAL;
}
public static String getDeviceModel() {
return System.getProperties().getProperty(CIMConstant.ConfigKey.DEVICE_MODEL);
}
public static String getClientVersion() {
return System.getProperties().getProperty(CIMConstant.ConfigKey.CLIENT_VERSION);
}
public static String getAccount() {
return System.getProperties().getProperty(CIMConstant.ConfigKey.CLIENT_ACCOUNT);
}
public static void setAccount(String account) {
System.getProperties().put(CIMConstant.ConfigKey.CLIENT_ACCOUNT, account);
}
public static void setClientVersion(String version) {
System.getProperties().put(CIMConstant.ConfigKey.CLIENT_VERSION, version);
}
public static void setDeviceModel(String model) {
System.getProperties().put(CIMConstant.ConfigKey.DEVICE_MODEL, model);
}
private static String getLocalMac() {
InetAddress ia;
try {
ia = InetAddress.getLocalHost();
byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
StringBuffer sb = new StringBuffer("");
for(int i=0; i<mac.length; i++) {
if(i!=0) {
for (int i = 0; i < mac.length; i++) {
if (i != 0) {
sb.append("-");
}
//字节转换为整数
int temp = mac[i]&0xff;
// 字节转换为整数
int temp = mac[i] & 0xff;
String str = Integer.toHexString(temp);
if(str.length()==1) {
sb.append("0"+str);
}else {
if (str.length() == 1) {
sb.append("0" + str);
} else {
sb.append(str);
}
}
@ -289,7 +282,7 @@ public class CIMPushManager {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

View File

@ -20,73 +20,62 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.client;
import com.farsunset.cim.sdk.client.model.Intent;
import com.farsunset.cim.sdk.client.model.SentBody;
/**
* 与服务端连接服务
*
*/
public class CIMPushService {
public class CIMPushService {
protected final static int DEF_CIM_PORT = 23456;
protected final static int DEF_CIM_PORT = 23456;
private CIMConnectorManager manager;
private static CIMPushService service;
public static CIMPushService getInstance(){
if (service==null){
service = new CIMPushService();
}
public static CIMPushService getInstance() {
if (service == null) {
service = new CIMPushService();
}
return service;
}
public CIMPushService()
{
manager = CIMConnectorManager.getManager();
}
public void onStartCommand(Intent intent) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if(CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action))
{
String host = CIMCacheToolkit.getInstance().getString(CIMCacheToolkit.KEY_CIM_SERVIER_HOST);
int port =CIMCacheToolkit.getInstance().getInt(CIMCacheToolkit.KEY_CIM_SERVIER_PORT);
manager.connect(host,port);
}
if(CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action))
{
manager.send((SentBody) intent.getExtra(SentBody.class.getName()));
}
if(CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action))
{
manager.closeSession();
}
if(CIMPushManager.ACTION_DESTORY.equals(action))
{
manager.destroy();
}
if(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action) && !manager.isConnected())
{
String host = CIMCacheToolkit.getInstance().getString(CIMCacheToolkit.KEY_CIM_SERVIER_HOST);
int port =CIMCacheToolkit.getInstance().getInt( CIMCacheToolkit.KEY_CIM_SERVIER_PORT);
manager.connect(host,port);
}
}
public CIMPushService() {
manager = CIMConnectorManager.getManager();
}
public void onStartCommand(Intent intent) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) {
String host = CIMCacheManager.getInstance().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = CIMCacheManager.getInstance().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT);
manager.connect(host, port);
}
if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) {
manager.send((SentBody) intent.getExtra(SentBody.class.getName()));
}
if (CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action)) {
manager.closeSession();
}
if (CIMPushManager.ACTION_DESTORY.equals(action)) {
manager.destroy();
}
if (CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action) && !manager.isConnected()) {
String host = CIMCacheManager.getInstance().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = CIMCacheManager.getInstance().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT);
manager.connect(host, port);
}
}
}

View File

@ -21,100 +21,97 @@
*/
package com.farsunset.cim.sdk.client.constant;
/**
/**
* 常量
*/
public interface CIMConstant {
long RECONN_INTERVAL_TIME= 30 * 1000;
//消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
public interface CIMConstant {
long RECONN_INTERVAL_TIME = 30 * 1000;
// 消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
int DATA_HEADER_LENGTH = 3;
public static interface ReturnCode{
String CODE_404 ="404";
String CODE_403 ="403";
String CODE_405 ="405";
String CODE_200 ="200";
String CODE_206 ="206";
String CODE_500 ="500";
}
public static interface ConfigKey{
public static String DEVICE_MODEL ="client.model";
public static String CLIENT_VERSION ="client.version";
public static String CLIENT_ACCOUNT ="client.account";
public static interface ReturnCode {
String CODE_404 = "404";
String CODE_403 = "403";
String CODE_405 = "405";
String CODE_200 = "200";
String CODE_206 = "206";
String CODE_500 = "500";
}
public static interface ProtobufType{
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey{
String CLIENT_BIND ="client_bind";
String CLIENT_LOGOUT ="client_logout";
public static interface ConfigKey {
public static String DEVICE_MODEL = "client.model";
public static String CLIENT_VERSION = "client.version";
public static String CLIENT_ACCOUNT = "client.account";
}
public static interface ProtobufType {
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey {
String CLIENT_BIND = "client_bind";
String CLIENT_LOGOUT = "client_logout";
@Deprecated
String CLIENT_PULL_MESSAGE ="client_pull_message";
String CLIENT_PULL_MESSAGE = "client_pull_message";
}
public static interface MessageAction{
//被其他设备登录挤下线消息
String ACTION_999 ="999";
//被系统禁用消息
String ACTION_444 ="444";
}
public static interface IntentAction{
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
// 未知异常
String ACTION_UNCAUGHT_EXCEPTION = "com.farsunset.cim.UNCAUGHT_EXCEPTION";
//重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
}
public static interface MessageAction {
// 被其他设备登录挤下线消息
String ACTION_999 = "999";
// 被系统禁用消息
String ACTION_444 = "444";
}
public static interface IntentAction {
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
// 未知异常
String ACTION_UNCAUGHT_EXCEPTION = "com.farsunset.cim.UNCAUGHT_EXCEPTION";
// 重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
}
}

View File

@ -21,15 +21,14 @@
*/
package com.farsunset.cim.sdk.client.exception;
public class NetworkDisconnectedException extends Exception {
private static final long serialVersionUID = 1L;
public NetworkDisconnectedException() {
super();
}
public NetworkDisconnectedException(String s) {
super(s);
}

View File

@ -21,9 +21,8 @@
*/
package com.farsunset.cim.sdk.client.exception;
public class SessionDisconnectedException extends Exception {
private static final long serialVersionUID = 1L;
public SessionDisconnectedException() {

View File

@ -26,7 +26,7 @@ import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
/**
/**
* android客户端端消息 编码解码器
*/
public class ClientMessageCodecFactory implements ProtocolCodecFactory {
@ -34,23 +34,23 @@ public class ClientMessageCodecFactory implements ProtocolCodecFactory {
/**
* 消息编码器
*/
private final ClientMessageEncoder encoder;
/**
private final ClientMessageEncoder encoder;
/**
* 消息解码器
*/
private final ClientMessageDecoder decoder;
private final ClientMessageDecoder decoder;
public ClientMessageCodecFactory() {
encoder = new ClientMessageEncoder();
decoder = new ClientMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
public ClientMessageCodecFactory() {
encoder = new ClientMessageEncoder();
decoder = new ClientMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.client.filter;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
@ -35,78 +34,72 @@ import com.farsunset.cim.sdk.client.model.ReplyBody;
import com.farsunset.cim.sdk.model.proto.MessageProto;
import com.farsunset.cim.sdk.model.proto.ReplyBodyProto;
import com.google.protobuf.InvalidProtocolBufferException;
/**
* 客户端消息解码
* 客户端消息解码
*/
public class ClientMessageDecoder extends CumulativeProtocolDecoder {
protected final Logger logger = Logger.getLogger(ClientMessageDecoder.class);
@Override
public boolean doDecode(IoSession iosession, IoBuffer iobuffer,
ProtocolDecoderOutput out) throws Exception {
public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
/**
* 消息头3位
*/
if (iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH) {
return false;
}
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv = iobuffer.get();// int 低位
byte hv = iobuffer.get();// int 高位
int conetnLength = getContentLength(lv, hv);
// 如果消息体没有接收完整则重置读取等待下一次重新读取
if (conetnLength > iobuffer.remaining()) {
iobuffer.reset();
return false;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes, conetnType);
if (message != null) {
out.write(message);
}
/**
* 消息头3位
*/
if(iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH){
return false;
}
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv =iobuffer.get();//int 低位
byte hv =iobuffer.get();//int 高位
int conetnLength = getContentLength(lv,hv);
//如果消息体没有接收完整则重置读取等待下一次重新读取
if(conetnLength > iobuffer.remaining()){
iobuffer.reset();
return false;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes,conetnType);
if(message!=null){
out.write(message);
}
return true;
}
private Object mappingMessageObject(byte[] bytes,byte type) throws InvalidProtocolBufferException {
if(CIMConstant.ProtobufType.S_H_RQ == type)
{
private Object mappingMessageObject(byte[] bytes, byte type) throws InvalidProtocolBufferException {
if (CIMConstant.ProtobufType.S_H_RQ == type) {
HeartbeatRequest request = HeartbeatRequest.getInstance();
logger.info(request.toString());
return request;
}
if(CIMConstant.ProtobufType.REPLYBODY == type)
{
if (CIMConstant.ProtobufType.REPLYBODY == type) {
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bytes);
ReplyBody body = new ReplyBody();
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
body.setCode(bodyProto.getCode());
body.setMessage(bodyProto.getMessage());
logger.info(body.toString());
return body;
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
body.setCode(bodyProto.getCode());
body.setMessage(bodyProto.getMessage());
logger.info(body.toString());
return body;
}
if(CIMConstant.ProtobufType.MESSAGE == type)
{
if (CIMConstant.ProtobufType.MESSAGE == type) {
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bytes);
Message message = new Message();
message.setMid(bodyProto.getMid());
@ -118,25 +111,26 @@ public class ClientMessageDecoder extends CumulativeProtocolDecoder {
message.setExtra(bodyProto.getExtra());
message.setTimestamp(bodyProto.getTimestamp());
message.setFormat(bodyProto.getFormat());
logger.info(message.toString());
return message;
return message;
}
return null;
}
/**
/**
* 解析消息体长度
*
* @param type
* @param length
* @return
*/
private int getContentLength(byte lv,byte hv){
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l| (h <<= 8));
private int getContentLength(byte lv, byte hv) {
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l | (h <<= 8));
}
}

View File

@ -29,45 +29,48 @@ import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import com.farsunset.cim.sdk.client.constant.CIMConstant;
import com.farsunset.cim.sdk.client.model.Protobufable;
/**
* 客户端消息发送前进行编码
* 客户端消息发送前进行编码
*/
public class ClientMessageEncoder extends ProtocolEncoderAdapter {
protected final Logger logger = Logger.getLogger(ClientMessageEncoder.class);
@Override
public void encode(IoSession iosession, Object object, ProtocolEncoderOutput out) throws Exception {
if(object instanceof Protobufable){
Protobufable data = (Protobufable) object;
byte[] byteArray = data.getByteArray();
IoBuffer buff = IoBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH).setAutoExpand(true);
buff.put(createHeader(data.getType(),byteArray.length));
buff.put(byteArray);
buff.flip();
if (object instanceof Protobufable) {
Protobufable data = (Protobufable) object;
byte[] byteArray = data.getByteArray();
IoBuffer buff = IoBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH).setAutoExpand(true);
buff.put(createHeader(data.getType(), byteArray.length));
buff.put(byteArray);
buff.flip();
out.write(buff);
//打印出收到的消息
// 打印出收到的消息
logger.info(data.toString());
}
}
}
/**
* 消息体最大为65535
*
* @param type
* @param length
* @return
*/
private byte[] createHeader(byte type,int length){
private byte[] createHeader(byte type, int length) {
byte[] header = new byte[CIMConstant.DATA_HEADER_LENGTH];
header[0] = type;
header[1] = (byte) (length & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
return header;
}
}

View File

@ -29,35 +29,34 @@ import com.farsunset.cim.sdk.client.constant.CIMConstant;
* 服务端心跳请求
*
*/
public class HeartbeatRequest implements Serializable,Protobufable {
public class HeartbeatRequest implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
private static final String CMD_HEARTBEAT_RESPONSE = "SR";
private static HeartbeatRequest object = new HeartbeatRequest();
private HeartbeatRequest(){
private HeartbeatRequest() {
}
public static HeartbeatRequest getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@Override
public byte getType() {
return CIMConstant.ProtobufType.S_H_RQ;
}
}

View File

@ -28,27 +28,28 @@ import com.farsunset.cim.sdk.client.constant.CIMConstant;
/**
* 客户端心跳响应
*/
public class HeartbeatResponse implements Serializable,Protobufable {
public class HeartbeatResponse implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse(){
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse() {
}
public static HeartbeatResponse getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@ -56,5 +57,5 @@ public class HeartbeatResponse implements Serializable,Protobufable {
public byte getType() {
return CIMConstant.ProtobufType.C_H_RS;
}
}

View File

@ -23,6 +23,7 @@ package com.farsunset.cim.sdk.client.model;
import java.io.Serializable;
import java.util.HashMap;
/**
* java |android 客户端请求结构
*
@ -35,14 +36,13 @@ public class Intent implements Serializable {
private HashMap<String, Object> data = new HashMap<String, Object>();
public Intent() {
}
public Intent(String action) {
this.action = action;
}
public String getAction() {
return action;
}
@ -51,18 +51,19 @@ public class Intent implements Serializable {
this.action = action;
}
public void putExtra(String key , Object value){
public void putExtra(String key, Object value) {
data.put(key, value);
}
public Object getExtra(String key){
public Object getExtra(String key) {
return data.get(key);
}
public long getLongExtra(String key, long defValue) {
Object v = getExtra(key);
try{
try {
return Long.parseLong(v.toString());
}catch(Exception e){
} catch (Exception e) {
return defValue;
}
}

View File

@ -30,13 +30,11 @@ public class Message implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 消息类型用户自定义消息类别
*/
private String mid;
/**
* 消息类型用户自定义消息类别
*/
@ -59,8 +57,6 @@ public class Message implements Serializable {
*/
private String receiver;
/**
* content 内容格式
*/
@ -72,12 +68,11 @@ public class Message implements Serializable {
private String extra;
private long timestamp;
public Message()
{
public Message() {
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -86,14 +81,14 @@ public class Message implements Serializable {
this.timestamp = timestamp;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTitle() {
return title;
}
@ -126,7 +121,6 @@ public class Message implements Serializable {
this.receiver = receiver;
}
public String getFormat() {
return format;
}
@ -134,17 +128,17 @@ public class Message implements Serializable {
public void setFormat(String format) {
this.format = format;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#Message#").append("\n");
buffer.append("mid:").append(mid).append("\n");
@ -158,7 +152,6 @@ public class Message implements Serializable {
buffer.append("timestamp:").append(timestamp);
return buffer.toString();
}
public String getMid() {
return mid;
@ -169,8 +162,7 @@ public class Message implements Serializable {
}
public boolean isNotEmpty(String txt) {
return txt != null && txt.trim().length()!=0;
return txt != null && txt.trim().length() != 0;
}
}

View File

@ -20,12 +20,13 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.client.model;
/**
* 需要向另一端发送的结构体
*/
public interface Protobufable {
byte[] getByteArray();
byte getType();
}

View File

@ -25,25 +25,25 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 请求应答对象
*
*/
public class ReplyBody implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 请求key
*/
private String key;
/**
* 返回码
*/
private String code;
/**
* 返回说明
*/
@ -54,14 +54,13 @@ public class ReplyBody implements Serializable {
*/
private HashMap<String, String> data;
private long timestamp;
public ReplyBody()
{
public ReplyBody() {
data = new HashMap<String, String>();
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -70,8 +69,6 @@ public class ReplyBody implements Serializable {
this.timestamp = timestamp;
}
public String getKey() {
return key;
}
@ -81,8 +78,8 @@ public class ReplyBody implements Serializable {
}
public void put(String k, String v) {
if(v!=null && k!=null){
data.put(k, v);
if (v != null && k != null) {
data.put(k, v);
}
}
@ -105,8 +102,8 @@ public class ReplyBody implements Serializable {
public void putAll(Map<String, String> map) {
data.putAll(map);
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
@ -118,24 +115,21 @@ public class ReplyBody implements Serializable {
this.code = code;
}
public String toString()
{
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#ReplyBody#").append("\n");
buffer.append("key:").append(this.getKey()).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
buffer.append("code:").append(code).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}

View File

@ -28,17 +28,18 @@ import java.util.Set;
import com.farsunset.cim.sdk.client.constant.CIMConstant;
import com.farsunset.cim.sdk.model.proto.SentBodyProto;
/**
* java |android 客户端请求结构
*
*/
public class SentBody implements Serializable,Protobufable {
public class SentBody implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private String key;
private HashMap<String, String> data = new HashMap<String, String>();;
private HashMap<String, String> data = new HashMap<String, String>();;
private long timestamp;
@ -67,19 +68,19 @@ public class SentBody implements Serializable,Protobufable {
}
public void put(String k, String v) {
if(v!=null && k!=null){
data.put(k, v);
if (v != null && k != null) {
data.put(k, v);
}
}
public void putAll(Map<String, String> map) {
data.putAll(map);
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
public void remove(String k) {
data.remove(k);
}
@ -87,34 +88,34 @@ public class SentBody implements Serializable,Protobufable {
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#SentBody#").append("\n");;
buffer.append("#SentBody#").append("\n");
;
buffer.append("key:").append(key).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}
@Override
public byte[] getByteArray() {
SentBodyProto.Model.Builder builder = SentBodyProto.Model.newBuilder();
builder.setKey(key);
builder.setTimestamp(timestamp);
if(!data.isEmpty()){
if (!data.isEmpty()) {
builder.putAllData(data);
}
return builder.build().toByteArray();
}
@Override
public byte getType() {
return CIMConstant.ProtobufType.SENTBODY;
}
}

View File

@ -21,41 +21,39 @@
*/
package com.farsunset.cim.sdk.server.constant;
/**
/**
* 常量
*/
public interface CIMConstant {
//消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
public interface CIMConstant {
// 消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
int DATA_HEADER_LENGTH = 3;
public static interface ReturnCode{
String CODE_200 ="200";
String CODE_404 ="404";
String CODE_403 ="403";
String CODE_500 ="500";
public static interface ReturnCode {
String CODE_200 = "200";
String CODE_404 = "404";
String CODE_403 = "403";
String CODE_500 = "500";
}
String SESSION_KEY ="account";
String HEARTBEAT_KEY ="heartbeat";
public static interface ProtobufType{
String SESSION_KEY = "account";
String HEARTBEAT_KEY = "heartbeat";
public static interface ProtobufType {
byte S_H_RQ = 1;
byte C_H_RS = 0;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
byte REPLYBODY = 4;
}
public static interface MessageAction{
//被其他设备登录挤下线消息
String ACTION_999 ="999";
}
public static interface MessageAction {
// 被其他设备登录挤下线消息
String ACTION_999 = "999";
}
}

View File

@ -26,26 +26,26 @@ import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
/**
/**
* 服务端消息 编码解码器
*/
public class ServerMessageCodecFactory implements ProtocolCodecFactory {
private final ServerMessageEncoder encoder;
private final ServerMessageEncoder encoder;
private final ServerMessageDecoder decoder;
public ServerMessageCodecFactory() {
encoder = new ServerMessageEncoder();
decoder = new ServerMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
private final ServerMessageDecoder decoder;
public ServerMessageCodecFactory() {
encoder = new ServerMessageEncoder();
decoder = new ServerMessageDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
}

View File

@ -25,11 +25,11 @@ import org.apache.mina.filter.codec.demux.DemuxingProtocolDecoder;
import com.farsunset.cim.sdk.server.filter.decoder.AppMessageDecoder;
import com.farsunset.cim.sdk.server.filter.decoder.WebMessageDecoder;
/**
* 服务端接收消息解码
* 服务端接收消息解码
*/
public class ServerMessageDecoder extends DemuxingProtocolDecoder {
public ServerMessageDecoder() {
addMessageDecoder(new AppMessageDecoder());

View File

@ -105,8 +105,8 @@ public class ServerMessageEncoder extends ProtocolEncoderAdapter {
}
/**
* 发送到websocket的数据需要进行相关格式转换
* 对传入数据进行无掩码转换
* 发送到websocket的数据需要进行相关格式转换 对传入数据进行无掩码转换
*
* @param data
* @return
*/

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.server.filter.decoder;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
@ -31,96 +32,91 @@ import com.farsunset.cim.sdk.server.constant.CIMConstant;
import com.farsunset.cim.sdk.server.model.HeartbeatResponse;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.sdk.server.model.proto.SentBodyProto;
/**
* 服务端接收消息解码
* 服务端接收消息解码
*/
public class AppMessageDecoder extends MessageDecoderAdapter {
protected final Logger logger = Logger.getLogger(AppMessageDecoder.class);
@Override
public MessageDecoderResult decodable(IoSession arg0, IoBuffer iobuffer) {
if(iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH){
return NEED_DATA;
}
/**
* 原生SDK只会发送2种类型消息 1个心跳类型 另一个是sendbody报文的第一个字节为消息类型
*/
byte conetnType = iobuffer.get();
if(conetnType == CIMConstant.ProtobufType.C_H_RS || conetnType == CIMConstant.ProtobufType.SENTBODY) {
return OK;
}
if (iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH) {
return NEED_DATA;
}
/**
* 原生SDK只会发送2种类型消息 1个心跳类型 另一个是sendbody报文的第一个字节为消息类型
*/
byte conetnType = iobuffer.get();
if (conetnType == CIMConstant.ProtobufType.C_H_RS || conetnType == CIMConstant.ProtobufType.SENTBODY) {
return OK;
}
return NOT_OK;
}
@Override
public MessageDecoderResult decode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv =iobuffer.get();//int 低位
byte hv =iobuffer.get();//int 高位
int conetnLength = getContentLength(lv,hv);
//如果消息体没有接收完整则重置读取等待下一次重新读取
if(conetnLength > iobuffer.remaining()){
iobuffer.reset();
return NEED_DATA;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes,conetnType);
if(message != null){
out.write(message);
}
return OK;
public MessageDecoderResult decode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out)
throws Exception {
iobuffer.mark();
byte conetnType = iobuffer.get();
byte lv = iobuffer.get();// int 低位
byte hv = iobuffer.get();// int 高位
int conetnLength = getContentLength(lv, hv);
// 如果消息体没有接收完整则重置读取等待下一次重新读取
if (conetnLength > iobuffer.remaining()) {
iobuffer.reset();
return NEED_DATA;
}
byte[] dataBytes = new byte[conetnLength];
iobuffer.get(dataBytes, 0, conetnLength);
Object message = mappingMessageObject(dataBytes, conetnType);
if (message != null) {
out.write(message);
}
return OK;
}
public Object mappingMessageObject(byte[] data,byte type) throws Exception
{
if(CIMConstant.ProtobufType.C_H_RS == type)
{
public Object mappingMessageObject(byte[] data, byte type) throws Exception {
if (CIMConstant.ProtobufType.C_H_RS == type) {
HeartbeatResponse response = HeartbeatResponse.getInstance();
logger.info(response.toString());
return response;
}
if(CIMConstant.ProtobufType.SENTBODY == type)
{
if (CIMConstant.ProtobufType.SENTBODY == type) {
SentBodyProto.Model bodyProto = SentBodyProto.Model.parseFrom(data);
SentBody body = new SentBody();
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
logger.info(body.toString());
return body;
SentBody body = new SentBody();
body.setKey(bodyProto.getKey());
body.setTimestamp(bodyProto.getTimestamp());
body.putAll(bodyProto.getDataMap());
logger.info(body.toString());
return body;
}
return null;
return null;
}
/**
* 解析消息体长度
*
* @param type
* @param length
* @return
*/
private int getContentLength(byte lv,byte hv){
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l| (h <<= 8));
private int getContentLength(byte lv, byte hv) {
int l = (lv & 0xff);
int h = (hv & 0xff);
return (l | (h <<= 8));
}
}

View File

@ -45,7 +45,8 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
public static final byte HAS_EXTEND_DATA = 126;
public static final byte HAS_EXTEND_DATA_CONTINUE = 127;
public static final byte PAYLOADLEN = 0x7F;// 0111 1111
public static final Pattern SEC_KEY_PATTERN = Pattern.compile("^(Sec-WebSocket-Key:).+",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public static final Pattern SEC_KEY_PATTERN = Pattern.compile("^(Sec-WebSocket-Key:).+",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
protected final Logger logger = Logger.getLogger(WebMessageDecoder.class);
@ -55,11 +56,10 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
return NEED_DATA;
}
/**
* 原生SDK只会发送2种类型消息 1个心跳类型 另一个是sendbody报文的第一个字节为消息类型
* 如果非原生sdk发出的消息则认为是websocket发送的消息
* websocket发送的消息 第一个字节不可能等于C_H_RS或者SENTBODY
*/
/**
* 原生SDK只会发送2种类型消息 1个心跳类型 另一个是sendbody报文的第一个字节为消息类型
* 如果非原生sdk发出的消息则认为是websocket发送的消息 websocket发送的消息 第一个字节不可能等于C_H_RS或者SENTBODY
*/
byte conetnType = iobuffer.get();
if (conetnType == CIMConstant.ProtobufType.C_H_RS || conetnType == CIMConstant.ProtobufType.SENTBODY) {
return NOT_OK;
@ -104,7 +104,7 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
}
@Override
public MessageDecoderResult decode(IoSession iosession, IoBuffer in, ProtocolDecoderOutput out)throws Exception {
public MessageDecoderResult decode(IoSession iosession, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
in.get();
byte head = in.get();
byte datalength = (byte) (head & PAYLOADLEN);
@ -121,26 +121,26 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
// 获取掩码
byte[] mask = new byte[4];
in.get(mask);
data = new byte[in.remaining()];
in.get(data);
for (int i = 0; i < data.length; i++) {
// 数据进行异或运算
data[i] = (byte) (data[i] ^ mask[i % 4]);
}
handleSentBodyAndHeartPing(data,out);
handleSentBodyAndHeartPing(data, out);
} else {
data = new byte[in.remaining()];
in.get(data);
handleWebsocketHandshake(new String(data, "UTF-8"),out);
handleWebsocketHandshake(new String(data, "UTF-8"), out);
}
return OK;
}
private void handleWebsocketHandshake(String message,ProtocolDecoderOutput out) {
private void handleWebsocketHandshake(String message, ProtocolDecoderOutput out) {
SentBody body = new SentBody();
body.setKey(CIMNioSocketAcceptor.WEBSOCKET_HANDLER_KEY);
Matcher m = SEC_KEY_PATTERN.matcher(message);
if (m.find()) {
String foundstring = m.group();
@ -149,10 +149,9 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
out.write(body);
}
public void handleSentBodyAndHeartPing(byte[] data,ProtocolDecoderOutput out) throws UnsupportedEncodingException {
public void handleSentBodyAndHeartPing(byte[] data, ProtocolDecoderOutput out) throws UnsupportedEncodingException {
String message = new String(data, "UTF-8");
/**
* 只处理心跳响应以及sentbody消息
*/
@ -160,12 +159,11 @@ public class WebMessageDecoder extends MessageDecoderAdapter {
HeartbeatResponse response = HeartbeatResponse.getInstance();
logger.info(response.toString());
out.write(response);
}else if(data.length > 2)
{
} else if (data.length > 2) {
SentBody body = JSON.parseObject(message, SentBody.class);
logger.info(body.toString());
out.write(body);
}
}
}

View File

@ -47,108 +47,102 @@ import com.farsunset.cim.sdk.server.model.ReplyBody;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.sdk.server.session.CIMSession;
public class CIMNioSocketAcceptor extends IoHandlerAdapter implements KeepAliveMessageFactory{
public class CIMNioSocketAcceptor extends IoHandlerAdapter implements KeepAliveMessageFactory {
public final static String WEBSOCKET_HANDLER_KEY = "client_websocket_handshake";
public final static String CIMSESSION_CLOSED_HANDLER_KEY = "client_cimsession_closed";
private Logger logger = Logger.getLogger(CIMNioSocketAcceptor.class);
private HashMap<String, CIMRequestHandler> handlers = new HashMap<String, CIMRequestHandler>();
private IoAcceptor acceptor;
private int port;
private final int IDLE_TIME = 120;//
private final int TIME_OUT = 10;//
private final int READ_BUFFER_SIZE = 1024;//byte
private final int IDLE_TIME = 120;//
private final int TIME_OUT = 10;//
private final int READ_BUFFER_SIZE = 1024;// byte
public void bind() throws IOException
{
/**
* 预制websocket握手请求的处理
*/
handlers.put(WEBSOCKET_HANDLER_KEY, new WebsocketHandler());
acceptor = new NioSocketAcceptor();
acceptor.getSessionConfig().setReadBufferSize(READ_BUFFER_SIZE);
((DefaultSocketSessionConfig)acceptor.getSessionConfig()).setKeepAlive(true);
((DefaultSocketSessionConfig)acceptor.getSessionConfig()).setTcpNoDelay(true);
KeepAliveFilter keepAliveFilter = new KeepAliveFilter(this,IdleStatus.WRITER_IDLE);
keepAliveFilter.setRequestInterval(IDLE_TIME);
keepAliveFilter.setRequestTimeout(TIME_OUT);
keepAliveFilter.setForwardEvent(true);
acceptor.getFilterChain().addLast("executor",new ExecutorFilter());
acceptor.getFilterChain().addLast("logger",new LoggingFilter());
acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new ServerMessageCodecFactory()));
acceptor.getFilterChain().addLast("heartbeat",keepAliveFilter);
public void bind() throws IOException {
acceptor.setHandler(this);
acceptor.bind(new InetSocketAddress(port));
}
public void unbind()
{
acceptor.unbind();
}
public void sessionCreated(IoSession session) {
logger.warn("sessionCreated()... from "+session.getRemoteAddress()+" nid:" + session.getId());
/**
* 预制websocket握手请求的处理
*/
handlers.put(WEBSOCKET_HANDLER_KEY, new WebsocketHandler());
acceptor = new NioSocketAcceptor();
acceptor.getSessionConfig().setReadBufferSize(READ_BUFFER_SIZE);
((DefaultSocketSessionConfig) acceptor.getSessionConfig()).setKeepAlive(true);
((DefaultSocketSessionConfig) acceptor.getSessionConfig()).setTcpNoDelay(true);
KeepAliveFilter keepAliveFilter = new KeepAliveFilter(this, IdleStatus.WRITER_IDLE);
keepAliveFilter.setRequestInterval(IDLE_TIME);
keepAliveFilter.setRequestTimeout(TIME_OUT);
keepAliveFilter.setForwardEvent(true);
acceptor.getFilterChain().addLast("executor", new ExecutorFilter());
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ServerMessageCodecFactory()));
acceptor.getFilterChain().addLast("heartbeat", keepAliveFilter);
acceptor.setHandler(this);
acceptor.bind(new InetSocketAddress(port));
}
public void messageReceived(IoSession ios, Object message){
public void unbind() {
acceptor.unbind();
}
public void sessionCreated(IoSession session) {
logger.warn("sessionCreated()... from " + session.getRemoteAddress() + " nid:" + session.getId());
}
public void messageReceived(IoSession ios, Object message) {
SentBody body = (SentBody) message;
CIMRequestHandler handler = handlers.get(body.getKey());
if (handler == null) {
ReplyBody reply = new ReplyBody();
reply.setKey(body.getKey());
reply.setCode(CIMConstant.ReturnCode.CODE_404);
reply.setMessage("KEY:"+body.getKey()+" not defined on server");
reply.setMessage("KEY:" + body.getKey() + " not defined on server");
ios.write(reply);
} else {
ReplyBody reply = handler.process(new CIMSession(ios), body);
if(reply!=null)
{
if (reply != null) {
reply.setKey(body.getKey());
ios.write(reply);
}
ios.write(reply);
}
}
}
/**
*/
public void sessionClosed(IoSession session) {
CIMSession cimSession =new CIMSession(session);
logger.warn("sessionClosed()... from "+session.getRemoteAddress()+" nid:"+cimSession.getNid() +",isConnected:"+session.isConnected());
CIMSession cimSession = new CIMSession(session);
logger.warn("sessionClosed()... from " + session.getRemoteAddress() + " nid:" + cimSession.getNid()
+ ",isConnected:" + session.isConnected());
CIMRequestHandler handler = handlers.get(CIMSESSION_CLOSED_HANDLER_KEY);
if(handler!=null)
{
if (handler != null) {
handler.process(cimSession, null);
}
}
/**
*/
public void sessionIdle(IoSession session, IdleStatus status) {
logger.warn("sessionIdle()... from "+session.getRemoteAddress()+" nid:" + session.getId());
public void sessionIdle(IoSession session, IdleStatus status) {
logger.warn("sessionIdle()... from " + session.getRemoteAddress() + " nid:" + session.getId());
}
/**
*/
public void exceptionCaught(IoSession session, Throwable cause){
logger.error("exceptionCaught()... from "+session.getRemoteAddress()+" isConnected:"+session.isConnected()+" nid:" + session.getId(),cause);
public void exceptionCaught(IoSession session, Throwable cause) {
logger.error("exceptionCaught()... from " + session.getRemoteAddress() + " isConnected:" + session.isConnected()
+ " nid:" + session.getId(), cause);
session.closeNow();
}
@ -157,8 +151,6 @@ public class CIMNioSocketAcceptor extends IoHandlerAdapter implements KeepAliveM
public void messageSent(IoSession session, Object message) throws Exception {
}
@Override
public Object getRequest(IoSession session) {
return HeartbeatRequest.getInstance();
@ -178,26 +170,23 @@ public class CIMNioSocketAcceptor extends IoHandlerAdapter implements KeepAliveM
public boolean isResponse(IoSession arg0, Object arg1) {
return arg1 instanceof HeartbeatResponse;
}
public Map<Long,IoSession> getManagedSessions()
{
public Map<Long, IoSession> getManagedSessions() {
return acceptor.getManagedSessions();
}
public IoSession getManagedSession(Long nid)
{
if(nid == null)
{
public IoSession getManagedSession(Long nid) {
if (nid == null) {
return null;
}
return getManagedSessions().get(nid);
}
public void setAcceptor(IoAcceptor acceptor) {
this.acceptor = acceptor;
}
public void setPort(int port) {
this.port = port;
}
@ -205,5 +194,5 @@ public class CIMNioSocketAcceptor extends IoHandlerAdapter implements KeepAliveM
public void setHandlers(HashMap<String, CIMRequestHandler> handlers) {
this.handlers = handlers;
}
}

View File

@ -28,8 +28,8 @@ package com.farsunset.cim.sdk.server.handler;
import com.farsunset.cim.sdk.server.model.ReplyBody;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.sdk.server.session.CIMSession;
public interface CIMRequestHandler {
ReplyBody process(CIMSession session,SentBody message);
public interface CIMRequestHandler {
ReplyBody process(CIMSession session, SentBody message);
}

View File

@ -27,8 +27,10 @@ import com.farsunset.cim.sdk.server.model.ReplyBody;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.sdk.server.model.WebsocketResponse;
import com.farsunset.cim.sdk.server.session.CIMSession;
/**
* 处理websocket握手请求返回响应的报文给浏览器
*
* @author Iraid
*
*/

View File

@ -26,35 +26,36 @@ import java.io.UnsupportedEncodingException;
import com.farsunset.cim.sdk.server.constant.CIMConstant;
import com.farsunset.cim.sdk.server.model.feature.EncodeFormatable;
/**
* 服务端心跳请求
*
*/
public class HeartbeatRequest implements Serializable,EncodeFormatable {
public class HeartbeatRequest implements Serializable, EncodeFormatable {
private static final long serialVersionUID = 1L;
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
private static final String CMD_HEARTBEAT_RESPONSE = "SR";
private static HeartbeatRequest object = new HeartbeatRequest();
private HeartbeatRequest(){
private HeartbeatRequest() {
}
public static HeartbeatRequest getInstance() {
return object;
}
@Override
public byte[] getProtobufBody() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@Override
public byte[] getJSONBody() {
try {
@ -65,10 +66,9 @@ public class HeartbeatRequest implements Serializable,EncodeFormatable {
return null;
}
@Override
public byte getDataType() {
return CIMConstant.ProtobufType.S_H_RQ;
}
}

View File

@ -23,7 +23,6 @@ package com.farsunset.cim.sdk.server.model;
import java.io.Serializable;
/**
* 客户端心跳响应
*/
@ -42,10 +41,8 @@ public class HeartbeatResponse implements Serializable {
return object;
}
public String toString() {
return TAG;
}
}

View File

@ -27,20 +27,19 @@ import com.alibaba.fastjson.JSONObject;
import com.farsunset.cim.sdk.server.constant.CIMConstant;
import com.farsunset.cim.sdk.server.model.feature.EncodeFormatable;
import com.farsunset.cim.sdk.server.model.proto.MessageProto;
/**
* 消息对象
*/
public class Message implements Serializable,EncodeFormatable {
public class Message implements Serializable, EncodeFormatable {
private static final long serialVersionUID = 1L;
/**
* 消息类型用户自定义消息类别
*/
private String mid;
/**
* 消息类型用户自定义消息类别
*/
@ -74,13 +73,11 @@ public class Message implements Serializable,EncodeFormatable {
private String extra;
private long timestamp;
public Message()
{
public Message() {
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -89,14 +86,14 @@ public class Message implements Serializable,EncodeFormatable {
this.timestamp = timestamp;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTitle() {
return title;
}
@ -129,7 +126,6 @@ public class Message implements Serializable,EncodeFormatable {
this.receiver = receiver;
}
public String getFormat() {
return format;
}
@ -137,17 +133,14 @@ public class Message implements Serializable,EncodeFormatable {
public void setFormat(String format) {
this.format = format;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String getMid() {
return mid;
@ -156,7 +149,7 @@ public class Message implements Serializable,EncodeFormatable {
public void setMid(String mid) {
this.mid = mid;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
@ -174,8 +167,9 @@ public class Message implements Serializable,EncodeFormatable {
}
public boolean isNotEmpty(String txt) {
return txt != null && txt.trim().length()!=0;
return txt != null && txt.trim().length() != 0;
}
@Override
public byte[] getProtobufBody() {
MessageProto.Model.Builder builder = MessageProto.Model.newBuilder();
@ -188,21 +182,21 @@ public class Message implements Serializable,EncodeFormatable {
/**
* 下面字段可能为空
*/
if(content!=null){
builder.setContent(content);
if (content != null) {
builder.setContent(content);
}
if(title!=null){
builder.setTitle(title);
if (title != null) {
builder.setTitle(title);
}
if(extra!=null){
builder.setExtra(extra);
if (extra != null) {
builder.setExtra(extra);
}
if(format!=null){
builder.setFormat(format);
if (format != null) {
builder.setFormat(format);
}
return builder.build().toByteArray();
}
@Override
public byte[] getJSONBody() {
JSONObject json = new JSONObject();
@ -224,6 +218,7 @@ public class Message implements Serializable,EncodeFormatable {
}
return null;
}
@Override
public byte getDataType() {
return CIMConstant.ProtobufType.MESSAGE;

View File

@ -31,25 +31,25 @@ import com.alibaba.fastjson.JSONObject;
import com.farsunset.cim.sdk.server.constant.CIMConstant;
import com.farsunset.cim.sdk.server.model.feature.EncodeFormatable;
import com.farsunset.cim.sdk.server.model.proto.ReplyBodyProto;
/**
* 请求应答对象
*
*/
public class ReplyBody implements Serializable ,EncodeFormatable{
public class ReplyBody implements Serializable, EncodeFormatable {
private static final long serialVersionUID = 1L;
/**
* 请求key
*/
private String key;
/**
* 返回码
*/
private String code;
/**
* 返回说明
*/
@ -60,13 +60,12 @@ public class ReplyBody implements Serializable ,EncodeFormatable{
*/
private HashMap<String, String> data = new HashMap<String, String>();
private long timestamp;
public ReplyBody()
{
public ReplyBody() {
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -75,8 +74,6 @@ public class ReplyBody implements Serializable ,EncodeFormatable{
this.timestamp = timestamp;
}
public String getKey() {
return key;
}
@ -86,15 +83,15 @@ public class ReplyBody implements Serializable ,EncodeFormatable{
}
public void put(String k, String v) {
if(v!=null && k!=null){
data.put(k, v);
if (v != null && k != null) {
data.put(k, v);
}
}
public void putAll(Map<String, String> map) {
data.putAll(map);
}
public String get(String k) {
return data.get(k);
}
@ -111,7 +108,7 @@ public class ReplyBody implements Serializable ,EncodeFormatable{
this.message = message;
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
@ -124,45 +121,45 @@ public class ReplyBody implements Serializable ,EncodeFormatable{
}
@Override
public String toString()
{
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#ReplyBody#").append("\n");
buffer.append("key:").append(this.getKey()).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
buffer.append("code:").append(code).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}
@Override
public byte[] getProtobufBody() {
ReplyBodyProto.Model.Builder builder = ReplyBodyProto.Model.newBuilder();
builder.setCode(code);
if(message!=null){
if (message != null) {
builder.setMessage(message);
}
if(!data.isEmpty()){
if (!data.isEmpty()) {
builder.putAllData(data);
}
builder.setKey(key);
builder.setTimestamp(timestamp);
return builder.build().toByteArray();
}
@Override
public byte getDataType() {
return CIMConstant.ProtobufType.REPLYBODY;
}
@Override
public byte[] getJSONBody() {
JSONObject json = new JSONObject();

View File

@ -25,6 +25,7 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* java |android 客户端请求结构
*
@ -59,43 +60,41 @@ public class SentBody implements Serializable {
this.key = key;
}
public void remove(String k) {
data.remove(k);
}
public void put(String k, String v) {
if(v!=null && k!=null){
data.put(k, v);
if (v != null && k != null) {
data.put(k, v);
}
}
public void putAll(Map<String, String> map) {
data.putAll(map);
}
public Set<String> getKeySet() {
public Set<String> getKeySet() {
return data.keySet();
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#SentBody#").append("\n");;
buffer.append("#SentBody#").append("\n");
;
buffer.append("key:").append(key).append("\n");
buffer.append("timestamp:").append(timestamp).append("\n");
if(!data.isEmpty()){
if (!data.isEmpty()) {
buffer.append("data{").append("\n");
for(String key:getKeySet())
{
for (String key : getKeySet()) {
buffer.append(key).append(":").append(this.get(key)).append("\n");
}
buffer.append("}");
}
return buffer.toString();
}
}

View File

@ -22,26 +22,28 @@
package com.farsunset.cim.sdk.server.model;
import java.io.UnsupportedEncodingException;
/**
*websocket握手响应结果
* websocket握手响应结果
*
*/
public class WebsocketResponse{
public class WebsocketResponse {
private String token;
public WebsocketResponse(String token) {
this.token = token;
}
public byte[] getBytes() {
try {
try {
return toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
return null;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
@ -55,7 +57,7 @@ public class WebsocketResponse{
builder.append("\r\n");
builder.append("\r\n");
return builder.toString();
return builder.toString();
}
}

View File

@ -20,11 +20,14 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.server.model.feature;
/**
* 需要向另一端发送的结构体
*/
public interface EncodeFormatable {
byte[] getProtobufBody();
byte[] getJSONBody();
byte getDataType();
}

View File

@ -35,56 +35,53 @@ import com.farsunset.cim.sdk.server.constant.CIMConstant;
* IoSession包装类,集群时 将此对象存入表中
*/
public class CIMSession implements Serializable{
public class CIMSession implements Serializable {
/**
*
*/
private transient static final long serialVersionUID = 1L;
public transient static String ID = "ID";
public transient static String HOST = "HOST";
public transient static final int STATUS_ENABLED = 0;
public transient static final int STATUS_DISABLED = 1;
public transient static final int APNS_ON=1;
public transient static final int APNS_OFF=0;
public transient static String CHANNEL_IOS = "ios";
public transient static String CHANNEL_ANDROID = "android";
public transient static String CHANNEL_WINDOWS = "windows";
public transient static String CHANNEL_WP = "wp";
public transient static String CHANNEL_BROWSER = "browser";
public transient static String ID = "ID";
public transient static String HOST = "HOST";
public transient static final int STATUS_ENABLED = 0;
public transient static final int STATUS_DISABLED = 1;
public transient static final int APNS_ON = 1;
public transient static final int APNS_OFF = 0;
public transient static String CHANNEL_IOS = "ios";
public transient static String CHANNEL_ANDROID = "android";
public transient static String CHANNEL_WINDOWS = "windows";
public transient static String CHANNEL_WP = "wp";
public transient static String CHANNEL_BROWSER = "browser";
private transient IoSession session;
private String gid;//session全局ID
private Long nid;//session在本台服务器上的ID
private String deviceId;//客户端ID (设备号码+应用包名),ios为devicetoken
private String host;//session绑定的服务器IP
private String account;//session绑定的账号
private String channel;//终端设备类型
private String deviceModel;//终端设备型号
private String clientVersion;//终端应用版本
private String systemVersion;//终端系统版本
private String packageName;//终端应用包名
private Long bindTime;//登录时间
private Long heartbeat;//心跳时间
private Double longitude;//经度
private Double latitude;//维度
private String location;//位置
private int apnsAble;//apns推送状态
private String gid;// session全局ID
private Long nid;// session在本台服务器上的ID
private String deviceId;// 客户端ID (设备号码+应用包名),ios为devicetoken
private String host;// session绑定的服务器IP
private String account;// session绑定的账号
private String channel;// 终端设备类型
private String deviceModel;// 终端设备型号
private String clientVersion;// 终端应用版本
private String systemVersion;// 终端系统版本
private String packageName;// 终端应用包名
private Long bindTime;// 登录时间
private Long heartbeat;// 心跳时间
private Double longitude;// 经度
private Double latitude;// 维度
private String location;// 位置
private int apnsAble;// apns推送状态
private int status;// 状态
public CIMSession(IoSession session) {
this.session = session;
this.nid = session.getId();
}
public CIMSession()
{
public CIMSession() {
}
public String getAccount() {
return account;
@ -92,15 +89,10 @@ public class CIMSession implements Serializable{
public void setAccount(String account) {
this.account = account;
setAttribute(CIMConstant.SESSION_KEY, account);
}
public Double getLongitude() {
return longitude;
}
@ -133,9 +125,9 @@ public class CIMSession implements Serializable{
}
public void setGid(String gid) {
this.gid = gid;
setAttribute("gid", gid);
}
@ -151,14 +143,13 @@ public class CIMSession implements Serializable{
return deviceId;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
setAttribute("channel", channel);
}
@ -168,35 +159,29 @@ public class CIMSession implements Serializable{
public void setDeviceModel(String deviceModel) {
this.deviceModel = deviceModel;
setAttribute("deviceModel", deviceModel);
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
setAttribute("deviceId", deviceId);
}
public String getHost() {
return host;
}
public Long getBindTime() {
return bindTime;
}
public void setBindTime(Long bindTime) {
this.bindTime = bindTime;
setAttribute("bindTime", bindTime);
setAttribute("bindTime", bindTime);
}
public String getClientVersion() {
return clientVersion;
}
@ -206,10 +191,6 @@ public class CIMSession implements Serializable{
setAttribute("clientVersion", clientVersion);
}
public String getSystemVersion() {
return systemVersion;
}
@ -230,13 +211,10 @@ public class CIMSession implements Serializable{
public void setHost(String host) {
this.host = host;
setAttribute("host", host);
}
public int getApnsAble() {
return apnsAble;
}
@ -255,64 +233,58 @@ public class CIMSession implements Serializable{
setAttribute("status", status);
}
public void setAttribute(String key, Object value) {
if(session!=null)
session.setAttribute(key, value);
if (session != null)
session.setAttribute(key, value);
}
public boolean containsAttribute(String key) {
if(session!=null)
return session.containsAttribute(key);
if (session != null)
return session.containsAttribute(key);
return false;
}
public Object getAttribute(String key) {
if(session!=null)
return session.getAttribute(key);
if (session != null)
return session.getAttribute(key);
return null;
}
public void removeAttribute(String key) {
if(session!=null)
session.removeAttribute(key);
if (session != null)
session.removeAttribute(key);
}
public SocketAddress getRemoteAddress() {
if(session!=null)
return session.getRemoteAddress();
if (session != null)
return session.getRemoteAddress();
return null;
}
public boolean write(Object msg) {
if(session!=null)
{
WriteFuture future = session.write(msg);
future.awaitUninterruptibly(10 * 1000);
public boolean write(Object msg) {
if (session != null) {
WriteFuture future = session.write(msg);
future.awaitUninterruptibly(10 * 1000);
return future.isWritten();
}
return false;
}
public boolean isConnected() {
if(session != null)
{
if (session != null) {
return session.isConnected();
}
if(!isLocalhost())
{
if (!isLocalhost()) {
return status == STATUS_ENABLED;
}
return false;
}
public boolean isLocalhost()
{
public boolean isLocalhost() {
try {
String ip = InetAddress.getLocalHost().getHostAddress();
return ip.equals(host);
@ -320,20 +292,18 @@ public class CIMSession implements Serializable{
e.printStackTrace();
}
return false;
}
public void closeNow() {
if(session!=null)
session.closeNow();
if (session != null)
session.closeNow();
}
public void closeOnFlush() {
if(session!=null)
session.closeOnFlush();
if (session != null)
session.closeOnFlush();
}
public void setPackageName(String packageName) {
this.packageName = packageName;
@ -343,39 +313,37 @@ public class CIMSession implements Serializable{
public String getPackageName() {
return packageName;
}
public int hashCode(){
public int hashCode() {
return (deviceId + nid + host).hashCode();
}
public boolean equals(Object o) {
if(o instanceof CIMSession){
if (o instanceof CIMSession) {
return hashCode() == o.hashCode();
}
return false;
}
public boolean fromOtherDevice(Object o) {
public boolean fromOtherDevice(Object o) {
if (o instanceof CIMSession) {
CIMSession t = (CIMSession) o;
if(t.deviceId!=null && deviceId!=null)
{
if (t.deviceId != null && deviceId != null) {
return !t.deviceId.equals(deviceId);
}
}
}
}
return false;
}
public boolean fromCurrentDevice(Object o) {
public boolean fromCurrentDevice(Object o) {
return !fromOtherDevice(o);
}
public void setIoSession(IoSession session) {
this.session = session;
}
@ -383,30 +351,26 @@ public class CIMSession implements Serializable{
public IoSession getIoSession() {
return session;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("{");
buffer.append("\"").append("gid").append("\":").append("\"").append(gid).append("\"").append(",");
buffer.append("\"").append("nid").append("\":").append(nid).append(",");
buffer.append("\"").append("deviceId").append("\":").append("\"").append(deviceId).append("\"").append(",");
buffer.append("\"").append("host").append("\":").append("\"").append(host).append("\"").append(",");
buffer.append("\"").append("account").append("\":").append("\"").append(account).append("\"").append(",");
buffer.append("\"").append("channel").append("\":").append("\"").append(channel).append("\"").append(",");
buffer.append("\"").append("deviceModel").append("\":").append("\"").append(deviceModel).append("\"").append(",");
buffer.append("\"").append("deviceModel").append("\":").append("\"").append(deviceModel).append("\"")
.append(",");
buffer.append("\"").append("status").append("\":").append(status).append(",");
buffer.append("\"").append("apnsAble").append("\":").append(apnsAble).append(",");
buffer.append("\"").append("bindTime").append("\":").append(bindTime).append(",");
buffer.append("\"").append("heartbeat").append("\":").append(heartbeat);
buffer.append("}");
return buffer.toString();
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.server.session;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -27,70 +28,57 @@ import java.util.concurrent.atomic.AtomicInteger;
import com.farsunset.cim.sdk.server.constant.CIMConstant;
/**
* 自带默认 session管理实现 各位可以自行实现 AbstractSessionManager接口来实现自己的 session管理
*服务器集群时 须要将CIMSession 信息存入数据库或者nosql 第三方存储空间中便于所有服务器都可以访问
/**
* 自带默认 session管理实现 各位可以自行实现 AbstractSessionManager接口来实现自己的 session管理 服务器集群时
* 须要将CIMSession 信息存入数据库或者nosql 第三方存储空间中便于所有服务器都可以访问
*/
public class DefaultSessionManager implements SessionManager{
public class DefaultSessionManager implements SessionManager {
private static HashMap<String, CIMSession> sessions = new HashMap<String, CIMSession>();
private static HashMap<String,CIMSession> sessions =new HashMap<String,CIMSession>();
private static final AtomicInteger connectionsCounter = new AtomicInteger(0);
private static final AtomicInteger connectionsCounter = new AtomicInteger(0);
/**
*
*/
public void add(CIMSession session) {
if(session!=null)
{
session.setAttribute(CIMConstant.SESSION_KEY, session.getAccount());
sessions.put(session.getAccount(), session);
connectionsCounter.incrementAndGet();
}
}
/**
*
*/
public void add(CIMSession session) {
if (session != null) {
session.setAttribute(CIMConstant.SESSION_KEY, session.getAccount());
sessions.put(session.getAccount(), session);
connectionsCounter.incrementAndGet();
}
public CIMSession get(String account) {
return sessions.get(account);
}
}
public List<CIMSession> queryAll() {
List<CIMSession> list = new ArrayList<CIMSession>();
list.addAll(sessions.values());
return list;
}
public void remove(CIMSession session) {
sessions.remove(session.getAttribute(CIMConstant.SESSION_KEY));
}
public CIMSession get(String account) {
public void remove(String account) {
sessions.remove(account);
}
public boolean containsCIMSession(String account)
{
return sessions.containsKey(account);
}
return sessions.get(account);
}
public List<CIMSession> queryAll() {
List<CIMSession> list = new ArrayList<CIMSession>();
list.addAll(sessions.values());
return list;
}
public void remove(CIMSession session) {
sessions.remove(session.getAttribute(CIMConstant.SESSION_KEY));
}
public void remove(String account) {
sessions.remove(account);
}
public boolean containsCIMSession(String account) {
return sessions.containsKey(account);
}
@Override
public void update(CIMSession session) {
sessions.put(session.getAccount(), session);
}
}

View File

@ -23,43 +23,42 @@ package com.farsunset.cim.sdk.server.session;
import java.util.List;
/**
* 客户端的 session管理接口
* 可自行实现此接口管理session
* 客户端的 session管理接口 可自行实现此接口管理session
*/
public interface SessionManager {
public interface SessionManager {
/**
* 添加新的session
*/
public void add(CIMSession session);
/**
* 更新session
*/
public void update(CIMSession session);
/**
*
* @param account 客户端session的 key 一般可用 用户账号来对应session
* @param account
* 客户端session的 key 一般可用 用户账号来对应session
* @return
*/
CIMSession get(String account);
/**
* 获取所有session
*
* @return
*/
public List<CIMSession> queryAll();
/**
/**
* 删除session
*
* @param session
*/
public void remove(String account);
public void remove(String account);
}

View File

@ -5,6 +5,8 @@ var SDK_VERSION = "1.0.0";
var SDK_CHANNEL = "browser";
var APP_PACKAGE = "com.farsunset.webcim";
var ACCOUNT;
const ACTION_999 = "999";//特殊的消息类型,代表被服务端强制下线
var socket;
var manualStop = false;
var CIMWebBridge = new Object();
@ -36,7 +38,13 @@ CIMWebBridge.stop = function(){
manualStop = true;
socket.close();
};
CIMWebBridge.resume = function(){
manualStop = false;
CIMWebBridge.connection();
};
CIMWebBridge.innerOnConnectionSuccessed = function(){
if(typeof onConnectionSuccessed != 'undefined' && onConnectionSuccessed instanceof Function){
onConnectionSuccessed();
@ -53,12 +61,13 @@ CIMWebBridge.innerOnMessageReceived = function(e){
*/
if(data == CMD_HEARTBEAT_REQUEST){
socket.send(CMD_HEARTBEAT_RESPONSE);
return
return;
}
var json = JSON.parse(data);
if(json.contentType == "Message" && typeof onMessageReceived != 'undefined' && onMessageReceived instanceof Function){
onMessageReceived(json);
if(json.contentType == "Message"){
onInterceptMessageReceived(json);
return;
}
if(json.contentType == "ReplyBody" && typeof onReplyReceived != 'undefined' && onReplyReceived instanceof Function){
@ -76,6 +85,17 @@ CIMWebBridge.sendRequest = function(body){
socket.send(json);
};
function onInterceptMessageReceived(message){
//被强制下线之后,不再继续连接服务端
if(message.action == ACTION_999){
manualStop = true;
}
//收到消息后,将消息发送给页面
if(onMessageReceived instanceof Function){
onMessageReceived(message);
}
}
function getBrowser() {
var explorer = window.navigator.userAgent.toLowerCase() ;
// ie

View File

@ -49,6 +49,11 @@
function onMessageReceived(message)
{
if(message.acction == ACTION_999){
doHideDialog('MessageDialog');
doShowDialog('LoginDialog');
return ;
}
$("#messageList").append("<div class='alert alert-info' >"+message.content+"</div>");
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.admin.action;
import java.io.IOException;
import org.apache.struts2.ServletActionContext;
@ -32,35 +31,31 @@ import com.farsunset.cim.sdk.server.model.Message;
import com.farsunset.cim.sdk.server.session.DefaultSessionManager;
import com.farsunset.cim.util.ContextHolder;
import com.opensymphony.xwork2.ActionSupport;
public class SessionAction extends ActionSupport {
/**
*
*/
*/
private static final long serialVersionUID = 1L;
public String list()
{
ServletActionContext.getRequest().setAttribute("sessionList", ((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager")).queryAll());
return "list";
public String list() {
ServletActionContext.getRequest().setAttribute("sessionList",
((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager")).queryAll());
return "list";
}
public void offline() throws IOException
{
String account = ServletActionContext.getRequest().getParameter("account");
Message msg = new Message();
msg.setAction(CIMConstant.MessageAction.ACTION_999);//强行下线消息类型
msg.setReceiver(account);
//向客户端 发送消息
ContextHolder.getBean(SystemMessagePusher.class).push(msg);
public void offline() throws IOException {
String account = ServletActionContext.getRequest().getParameter("account");
Message msg = new Message();
msg.setAction(CIMConstant.MessageAction.ACTION_999);// 强行下线消息类型
msg.setReceiver(account);
// 向客户端 发送消息
ContextHolder.getBean(SystemMessagePusher.class).push(msg);
}
}

View File

@ -37,108 +37,92 @@ import com.google.gson.Gson;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
/**
*
* @author farsunset (3979434@qq.com)
*/
public class MessageAction extends ActionSupport implements ModelDriven<Message>{
public class MessageAction extends ActionSupport implements ModelDriven<Message> {
/**
*
*/
private static final long serialVersionUID = 1L;
Message message = new Message();
/**
* 关于http参数获取 struts2 的模型驱动 比如 http 参数 sender=xiaomao&receiver=xiaogou
* struts自动会将参数的值 存入getModel()返回的对象的对应属性中即xiaomao会存入message.sender属性,xiaogou会存入message.receiver属性
* 省去了request.getParameter("sender")方式获取参数如果参数名在getModel()返回的对象中不存在则需要用request.getParameter()获取
* 其他相关*Action.java中 同理这里做统一说明!
*/
public String send() throws Exception {
HashMap<String,Object> datamap = new HashMap<String,Object>();
HashMap<String,String> data = new HashMap<String,String>();
/**
* 关于http参数获取 struts2 的模型驱动 比如 http 参数 sender=xiaomao&receiver=xiaogou
* struts自动会将参数的值
* 存入getModel()返回的对象的对应属性中即xiaomao会存入message.sender属性,xiaogou会存入message.receiver属性
* 省去了request.getParameter("sender")方式获取参数如果参数名在getModel()返回的对象中不存在则需要用request.getParameter()获取
* 其他相关*Action.java中 同理这里做统一说明!
*/
public String send() throws Exception {
HashMap<String, Object> datamap = new HashMap<String, Object>();
HashMap<String, String> data = new HashMap<String, String>();
ServletActionContext.getResponse().setContentType("text/json;charset=UTF-8");
datamap.put("code", 200);
try{
try {
checkParams();
message.setMid(StringUtil.getUUID());
if(Constants.MessageType.TYPE_2.equals(message.getAction()))
{
//向客户端 发送消息
ContextHolder.getBean(SystemMessagePusher.class).push(message);
}else
{
//向客户端 发送消息
((DefaultMessagePusher)ContextHolder.getBean("messagePusher")).push(message);
if (Constants.MessageType.TYPE_2.equals(message.getAction())) {
// 向客户端 发送消息
ContextHolder.getBean(SystemMessagePusher.class).push(message);
} else {
// 向客户端 发送消息
((DefaultMessagePusher) ContextHolder.getBean("messagePusher")).push(message);
}
data.put("id", message.getMid());
data.put("createTime", String.valueOf(message.getTimestamp()));
datamap.put("data", data);
}catch(Exception e){
data.put("id", message.getMid());
data.put("createTime", String.valueOf(message.getTimestamp()));
datamap.put("data", data);
} catch (Exception e) {
datamap.put("code", 500);
e.printStackTrace();
}
ServletActionContext.getResponse().getWriter().print(new Gson().toJson(datamap));
return null;
}
/**
* 文件由客户端发往阿里云 OSS 存储
* @param messageServiceImpl
*/
/* private void fileHandler(Message mo, HttpServletRequest request) throws IOException
{
if(request instanceof MultiPartRequestWrapper){
MultiPartRequestWrapper pr = (MultiPartRequestWrapper) request;
if(pr.getFiles("file")!=null)
{
File file = pr.getFiles("file")[0];
String fileType = request.getParameter("fileType");
String dir = dirMap.get(fileType);
if(StringUtils.isEmpty(dir))
{
throw new IllegalArgumentException("fileType:" +fileType+" 未定义" );
}
String path = request.getSession().getServletContext().getRealPath(dir);
String uuid=UUID.randomUUID().toString().replaceAll("-", "");
File des = new File(path+"/"+uuid);
FileUtil.copyFile(file, des);
mo.setFile(dir+"/"+uuid);
mo.setFileType(fileType);
}
}
}*/
private void checkParams() throws ServletRequestBindingException
{
if(StringUtils.isEmpty(message.getReceiver()))
{
throw new IllegalArgumentException("receiver 不能为空!");
}
}
ServletActionContext.getResponse().getWriter().print(new Gson().toJson(datamap));
return null;
}
/**
* 文件由客户端发往阿里云 OSS 存储
*
* @param messageServiceImpl
*/
/*
* private void fileHandler(Message mo, HttpServletRequest request) throws
* IOException { if(request instanceof MultiPartRequestWrapper){
* MultiPartRequestWrapper pr = (MultiPartRequestWrapper) request;
* if(pr.getFiles("file")!=null) { File file = pr.getFiles("file")[0];
*
* String fileType = request.getParameter("fileType"); String dir =
* dirMap.get(fileType); if(StringUtils.isEmpty(dir)) { throw new
* IllegalArgumentException("fileType:" +fileType+" 未定义" );
*
* } String path = request.getSession().getServletContext().getRealPath(dir);
* String uuid=UUID.randomUUID().toString().replaceAll("-", ""); File des = new
* File(path+"/"+uuid); FileUtil.copyFile(file, des); mo.setFile(dir+"/"+uuid);
* mo.setFileType(fileType); } }
*
* }
*/
private void checkParams() throws ServletRequestBindingException {
if (StringUtils.isEmpty(message.getReceiver())) {
throw new IllegalArgumentException("receiver 不能为空!");
}
}
@Override
public Message getModel() {
// TODO Auto-generated method stub
return message;
}
}

View File

@ -34,29 +34,28 @@ import com.farsunset.cim.sdk.server.session.CIMSession;
import com.farsunset.cim.sdk.server.session.DefaultSessionManager;
import com.farsunset.cim.util.ContextHolder;
import com.farsunset.cim.util.StringUtil;
/**
* 账号绑定实现
*
*/
*/
public class BindHandler implements CIMRequestHandler {
protected final Logger logger = Logger.getLogger(BindHandler.class);
public ReplyBody process(CIMSession newSession, SentBody message) {
DefaultSessionManager sessionManager = ((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager"));
DefaultSessionManager sessionManager = ((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager"));
ReplyBody reply = new ReplyBody();
reply.setCode(CIMConstant.ReturnCode.CODE_200);
try {
try {
String account = message.get("account");
newSession.setGid(StringUtil.getUUID());
newSession.setAccount(account);
newSession.setDeviceId(message.get("deviceId"));
newSession.setHost(InetAddress.getLocalHost().getHostAddress());
newSession.setChannel( message.get("channel"));
newSession.setChannel(message.get("channel"));
newSession.setDeviceModel(message.get("device"));
newSession.setClientVersion(message.get("version"));
newSession.setSystemVersion(message.get("osVersion"));
@ -65,72 +64,61 @@ public class BindHandler implements CIMRequestHandler {
/**
* 由于客户端断线服务端可能会无法获知的情况客户端重连时需要关闭旧的连接
*/
CIMSession oldSession = sessionManager.get(account);
CIMSession oldSession = sessionManager.get(account);
// 如果是账号已经在另一台终端登录则让另一个终端下线
if (newSession.fromOtherDevice(oldSession)) {
sendForceOfflineMessage(oldSession, account,newSession.getDeviceModel());
sendForceOfflineMessage(oldSession, account, newSession.getDeviceModel());
}
//如果是重复连接则直接返回
// 如果是重复连接则直接返回
if (newSession.equals(oldSession)) {
oldSession.setStatus(CIMSession.STATUS_ENABLED);
sessionManager.update(oldSession);
reply.put("sid", oldSession.getGid());
return reply;
}
closeQuietly(oldSession);
//第一次设置心跳时间为登录时间
// 第一次设置心跳时间为登录时间
newSession.setBindTime(System.currentTimeMillis());
newSession.setHeartbeat(System.currentTimeMillis());
sessionManager.add(newSession);
} catch (Exception e) {
reply.setCode(CIMConstant.ReturnCode.CODE_500);
e.printStackTrace();
}
logger.debug("bind :account:" +message.get("account")+"-----------------------------" +reply.getCode());
reply.put("sid", newSession.getGid());
logger.debug("bind :account:" + message.get("account") + "-----------------------------" + reply.getCode());
return reply;
}
private void sendForceOfflineMessage(CIMSession oldSession, String account,String deviceModel) {
private void sendForceOfflineMessage(CIMSession oldSession, String account, String deviceModel) {
Message msg = new Message();
msg.setMid(String.valueOf(System.currentTimeMillis()));
msg.setAction(CIMConstant.MessageAction.ACTION_999);// 强行下线消息类型
msg.setReceiver(account);
msg.setContent(deviceModel);
closeQuietly(oldSession,msg);
if (!oldSession.isLocalhost()) {
ContextHolder.getBean(SystemMessagePusher.class).push(msg);
}
closeQuietly(oldSession, msg);
ContextHolder.getBean(SystemMessagePusher.class).push(msg);
}
//同一设备切换网络时关闭旧的连接
private void closeQuietly(CIMSession oldSession){
if(oldSession!=null && oldSession.isConnected()){
// 同一设备切换网络时关闭旧的连接
private void closeQuietly(CIMSession oldSession) {
if (oldSession != null && oldSession.isConnected()) {
oldSession.removeAttribute(CIMConstant.SESSION_KEY);
oldSession.closeNow();
}
}
//不同设备同一账号登录时关闭旧的连接
private void closeQuietly(CIMSession oldSession,Message msg){
// 不同设备同一账号登录时关闭旧的连接
private void closeQuietly(CIMSession oldSession, Message msg) {
if (oldSession.isConnected()) {
oldSession.write(msg);
oldSession.removeAttribute(CIMConstant.SESSION_KEY);

View File

@ -41,18 +41,16 @@ public class SessionClosedHandler implements CIMRequestHandler {
public ReplyBody process(CIMSession ios, SentBody message) {
Object account =ios.getAttribute(CIMConstant.SESSION_KEY);
if(account == null){
return null;
}
DefaultSessionManager sessionManager = ((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager"));
Object account = ios.getAttribute(CIMConstant.SESSION_KEY);
if (account == null) {
return null;
}
DefaultSessionManager sessionManager = ((DefaultSessionManager) ContextHolder.getBean("CIMSessionManager"));
ios.removeAttribute(CIMConstant.SESSION_KEY);
sessionManager.remove(account.toString());
return null;
}
}

View File

@ -23,20 +23,17 @@ package com.farsunset.cim.push;
import com.farsunset.cim.sdk.server.model.Message;
/**
* 消息发送实接口
*
*/
public interface CIMMessagePusher {
/**
* 向用户发送消息
* @param msg
*/
/**
* 向用户发送消息
*
* @param msg
*/
public void push(Message msg);
}

View File

@ -29,68 +29,62 @@ import com.farsunset.cim.sdk.server.session.DefaultSessionManager;
* 消息发送实现类
*
*/
public class DefaultMessagePusher implements CIMMessagePusher {
public class DefaultMessagePusher implements CIMMessagePusher {
private DefaultSessionManager sessionManager;
public void setSessionManager(DefaultSessionManager sessionManager) {
public void setSessionManager(DefaultSessionManager sessionManager) {
this.sessionManager = sessionManager;
}
/**
* 向用户发送消息
* @param msg
*/
* 向用户发送消息
*
* @param msg
*/
public void push(Message msg) {
CIMSession session = sessionManager.get(msg.getReceiver());
/*
* 服务器集群时可以在此
* 判断当前session是否连接于本台服务器如果是继续往下走如果不是将此消息发往当前session连接的服务器并 return
* if(session!=null&&!session.isLocalhost()){//判断当前session是否连接于本台服务器如不是
* 服务器集群时可以在此 判断当前session是否连接于本台服务器如果是继续往下走如果不是将此消息发往当前session连接的服务器并
* return if(session!=null&&!session.isLocalhost()){//判断当前session是否连接于本台服务器如不是
* //发往目标服务器处理
* MessageDispatcher.execute(MessageUtil.transform(msg),session.getHost());
* return;
* }
* MessageDispatcher.execute(MessageUtil.transform(msg),session.getHost());
* return; }
*/
if (session != null && session.isConnected()) {
session.write(msg);
return;
}
// 如果用户标示了APNS ON 说明这是ios设备需要使用apns发送
if (session != null && session.getApnsAble() == CIMSession.APNS_ON) {
apnsPush(1,msg.getContent(),session.getDeviceId());
apnsPush(1, msg.getContent(), session.getDeviceId());
}
}
/**
* 引入javaapns相关jar
*
* @param badge
* @param content
* @param token
*/
private void apnsPush(int badge,String content,String token){
/*String password = "password";
String keystore = "p12 文件 绝对路径";
boolean isDebug = true;
PushNotificationPayload payload = PushNotificationPayload.complex();
try {
payload.addAlert(content);
payload.addBadge(1);
payload.addSound("default");
Push.payload(payload, keystore, password, isDebug, token);
} catch (Exception e) {
e.printStackTrace();
}*/
private void apnsPush(int badge, String content, String token) {
/*
* String password = "password"; String keystore = "p12 文件 绝对路径"; boolean
* isDebug = true;
*
* PushNotificationPayload payload = PushNotificationPayload.complex(); try {
* payload.addAlert(content); payload.addBadge(1); payload.addSound("default");
* Push.payload(payload, keystore, password, isDebug, token);
*
* } catch (Exception e) { e.printStackTrace(); }
*/
}
}

View File

@ -22,15 +22,14 @@
package com.farsunset.cim.push;
import com.farsunset.cim.sdk.server.model.Message;
public class SystemMessagePusher extends DefaultMessagePusher{
public class SystemMessagePusher extends DefaultMessagePusher {
@Override
public void push(Message message){
public void push(Message message) {
message.setSender("system");
super.push(message);
}
}

View File

@ -25,47 +25,41 @@ import java.util.List;
import com.farsunset.cim.sdk.server.session.CIMSession;
import com.farsunset.cim.sdk.server.session.SessionManager;
/**
* 集群 session管理实现示例 各位可以自行实现 AbstractSessionManager接口来实现自己的 session管理
*服务器集群时 须要将CIMSession 信息存入数据库或者nosql 第三方存储空间中便于所有服务器都可以访问
/**
* 集群 session管理实现示例 各位可以自行实现 AbstractSessionManager接口来实现自己的 session管理 服务器集群时
* 须要将CIMSession 信息存入数据库或者nosql 第三方存储空间中便于所有服务器都可以访问
*/
public class ClusterSessionManager implements SessionManager{
public class ClusterSessionManager implements SessionManager {
public CIMSession get(String account) {
public CIMSession get(String account) {
//这里查询数据库
/*CIMSession session = database.getSession(account);
session.setIoSession(ContextHolder.getBean(CIMNioSocketAcceptor.class).getManagedSessions().get(session.getNid()));
return session;*/
return null;
}
// 这里查询数据库
/*
* CIMSession session = database.getSession(account);
* session.setIoSession(ContextHolder.getBean(CIMNioSocketAcceptor.class).
* getManagedSessions().get(session.getNid())); return session;
*/
return null;
}
@Override
public List<CIMSession> queryAll() {
return null;
}
@Override
public List<CIMSession> queryAll() {
return null;
}
@Override
public void remove(String account) {
}
@Override
public void remove(String account) {
}
@Override
public void update(CIMSession session) {
}
@Override
public void add(CIMSession arg0) {
}
}

View File

@ -23,49 +23,47 @@ package com.farsunset.cim.util;
public interface Constants {
public class Common{
public final static String STATUS_1="1";
public final static String STATUS_0="0";
public final static String STATUS_2="2";
public final static String STATUS_3="3";
public final static String TYPR_1="1";
public final static String TYPR_2="2";
public class Common {
public final static String STATUS_1 = "1";
public final static String STATUS_0 = "0";
public final static String STATUS_2 = "2";
public final static String STATUS_3 = "3";
public final static String TYPR_1 = "1";
public final static String TYPR_2 = "2";
public final static String TYPR_9 = "9";
}
public class User{
public final static Integer SUCCESS_CODE=1;
public final static Integer ERROR_CODE=0;
public final static String User="User";
}
public class RequestParam
{
public final static String CURRENTPAGE="currentPage";
public final static String TYPE="type";
public class User {
public final static Integer SUCCESS_CODE = 1;
public final static Integer ERROR_CODE = 0;
public final static String User = "User";
}
public class RequestParam {
public final static String CURRENTPAGE = "currentPage";
public final static String TYPE = "type";
public static final String SIZE = "size";
}
public class Number{
public final static Integer INT_0=0;
public final static Integer INT_10=10;
public final static Integer INT_403=403;
}
public static interface MessageType{
//用户之间的普通消息
public static final String TYPE_0 = "0";
//系统向用户发送的普通消息
public static final String TYPE_2 = "2";
public class Number {
public final static Integer INT_0 = 0;
public final static Integer INT_10 = 10;
public final static Integer INT_403 = 403;
}
public static interface MessageType {
// 用户之间的普通消息
public static final String TYPE_0 = "0";
// 系统向用户发送的普通消息
public static final String TYPE_2 = "2";
}
}

View File

@ -24,25 +24,22 @@ package com.farsunset.cim.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ContextHolder implements ApplicationContextAware{
private static ApplicationContext context;
public static Object getBean(String name)
{
return context.getBean(name);
}
public static <T> T getBean(Class<T> c)
{
return context.getBean(c);
}
public class ContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
public static Object getBean(String name) {
return context.getBean(name);
}
public static <T> T getBean(Class<T> c) {
return context.getBean(c);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.util;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@ -39,56 +40,48 @@ import org.apache.http.util.EntityUtils;
import com.farsunset.cim.sdk.server.model.Message;
public class MessageDispatcher {
private static BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 20, TimeUnit.SECONDS,queue);;
public class MessageDispatcher {
private static BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 20, TimeUnit.SECONDS, queue);;
final static String sendUrl = "http://%1$s:8080/cim-servier/cgi/message_send.api";
public static void execute(final Message msg,final String ip)
{
executor.execute(new Runnable() {
public static void execute(final Message msg, final String ip) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
httpPost(String.format(sendUrl,ip),msg);
httpPost(String.format(sendUrl, ip), msg);
} catch (Exception e) {
e.printStackTrace();
}
}
});
});
}
private static String httpPost(String url,Message msg) throws Exception
{
private static String httpPost(String url, Message msg) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("mid", msg.getMid()));
nvps.add(new BasicNameValuePair("extra", msg.getExtra()));
nvps.add(new BasicNameValuePair("action", msg.getAction()));
nvps.add(new BasicNameValuePair("title", msg.getTitle()));
nvps.add(new BasicNameValuePair("content",msg.getContent()));
nvps.add(new BasicNameValuePair("sender", msg.getSender()));
nvps.add(new BasicNameValuePair("receiver",msg.getReceiver()));
nvps.add(new BasicNameValuePair("timestamp",String.valueOf(msg.getTimestamp())));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response2 = httpclient.execute(httpPost);
String data = null;
try {
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
data = EntityUtils.toString(entity2);
} finally {
response2.close();
}
return data;
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("mid", msg.getMid()));
nvps.add(new BasicNameValuePair("extra", msg.getExtra()));
nvps.add(new BasicNameValuePair("action", msg.getAction()));
nvps.add(new BasicNameValuePair("title", msg.getTitle()));
nvps.add(new BasicNameValuePair("content", msg.getContent()));
nvps.add(new BasicNameValuePair("sender", msg.getSender()));
nvps.add(new BasicNameValuePair("receiver", msg.getReceiver()));
nvps.add(new BasicNameValuePair("timestamp", String.valueOf(msg.getTimestamp())));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response2 = httpclient.execute(httpPost);
String data = null;
try {
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
data = EntityUtils.toString(entity2);
} finally {
response2.close();
}
return data;
}
}

View File

@ -25,44 +25,38 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class StringUtil {
public static boolean isEmpty(Object obj)
{
if(null == obj)
public static boolean isEmpty(Object obj) {
if (null == obj)
return true;
if("".equals(obj.toString().trim()))
{
if ("".equals(obj.toString().trim())) {
return true;
}
return false;
}
public static boolean isNotEmpty(Object obj)
{
public static boolean isNotEmpty(Object obj) {
return !isEmpty(obj);
}
public static String getSequenceId()
{
public static String getSequenceId() {
String mark = String.valueOf(System.currentTimeMillis());
return mark;
}
public static String getCurrentlyDateTime() {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyyMMddHHmmss");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
return dateFormat.format(new Date());
}
public static String transformDateTime(long t) {
Date date = new Date(t);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return dateFormat.format(date);
}
public static String getCurrentlyDate() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
return dateFormat.format(new Date());
@ -72,6 +66,5 @@ public class StringUtil {
// TODO Auto-generated method stub
return UUID.randomUUID().toString().replaceAll("-", "");
}
}

View File

@ -26,86 +26,76 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
class CIMCacheManager {
class CIMCacheManager {
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
public static final String KEY_DEVICE_ID = "KEY_DEVICE_ID";
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
public static final String KEY_CIM_SERVIER_HOST = "KEY_CIM_SERVIER_HOST";
public static final String KEY_CIM_SERVIER_PORT = "KEY_CIM_SERVIER_PORT";
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
public static void remove(Context context ,String key)
{
ContentResolver resolver = context.getContentResolver();
public static void remove(Context context, String key) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(Uri.parse(CIMCacheProvider.CONTENT_URI), key, null);
}
public static void putString(Context context, String key, String value) {
public static void putString(Context context ,String key,String value)
{
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("value", value);
values.put("key", key);
resolver.insert(Uri.parse(CIMCacheProvider.CONTENT_URI), values);
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("value", value);
values.put("key", key);
resolver.insert(Uri.parse(CIMCacheProvider.CONTENT_URI), values);
}
public static String getString(Context context ,String key)
{
public static String getString(Context context, String key) {
String value = null;
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(CIMCacheProvider.CONTENT_URI), new String[]{key}, null,null,null);
if (cursor!=null && cursor.moveToFirst())
{
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(CIMCacheProvider.CONTENT_URI), new String[] { key }, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
value = cursor.getString(0);
cursor.close();
}
closeQuietly(cursor);
return value;
}
private static void closeQuietly(Cursor cursor){
try{
if(cursor!=null)
cursor.close();
}catch(Exception e){}
private static void closeQuietly(Cursor cursor) {
try {
if (cursor != null)
cursor.close();
} catch (Exception e) {
}
}
public static void putBoolean(Context context,String key,boolean value)
{
putString(context,key,Boolean.toString(value));
public static void putBoolean(Context context, String key, boolean value) {
putString(context, key, Boolean.toString(value));
}
public static boolean getBoolean(Context context,String key)
{
String value = getString(context,key);
return value == null?false:Boolean.parseBoolean(value);
public static boolean getBoolean(Context context, String key) {
String value = getString(context, key);
return value == null ? false : Boolean.parseBoolean(value);
}
public static void putInt(Context context,String key,int value)
{
putString(context,key, String.valueOf(value));
public static void putInt(Context context, String key, int value) {
putString(context, key, String.valueOf(value));
}
public static int getInt(Context context,String key)
{
String value = getString(context,key);
return value == null?0:Integer.parseInt(value);
public static int getInt(Context context, String key) {
String value = getString(context, key);
return value == null ? 0 : Integer.parseInt(value);
}
}

View File

@ -29,13 +29,12 @@ import android.database.MatrixCursor;
import android.net.Uri;
public class CIMCacheProvider extends ContentProvider {
public static final String CONTENT_URI="content://com.farsunset.cim.provider";
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
public static final String CONTENT_URI = "content://com.farsunset.cim.provider";
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
@Override
public int delete(Uri arg0, String key, String[] arg2) {
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
return 0;
}
@ -48,7 +47,7 @@ public class CIMCacheProvider extends ContentProvider {
public Uri insert(Uri arg0, ContentValues values) {
String key = values.getAsString("key");
String value = values.getAsString("value");
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
return null;
}
@ -59,9 +58,9 @@ public class CIMCacheProvider extends ContentProvider {
@Override
public Cursor query(Uri arg0, String[] arg1, String key, String[] arg3, String arg4) {
MatrixCursor cursor = new MatrixCursor(new String[]{"value"});
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
cursor.addRow(new Object[]{value});
MatrixCursor cursor = new MatrixCursor(new String[] { "value" });
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
cursor.addRow(new Object[] { value });
return cursor;
}
@ -70,5 +69,4 @@ public class CIMCacheProvider extends ContentProvider {
return 0;
}
}

View File

@ -1,170 +0,0 @@
/**
* Copyright 2013-2023 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;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
class CIMCacheToolkit extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "CIM_CONFIG_INFO.db";
private static final int DATABASE_VERSION = 20160406;
private static final String TABLE_NAME = "T_CIM_CONFIG";
private static CIMCacheToolkit toolkit;
private static final String TABLE_SQL = "CREATE TABLE IF NOT EXISTS "+TABLE_NAME+" (KEY VARCHAR(64) PRIMARY KEY,VALUE TEXT)";
private static final String DELETE_SQL = "DELETE FROM "+TABLE_NAME+" WHERE KEY = ?";
private static final String QUERY_SQL = "SELECT VALUE FROM "+TABLE_NAME+" WHERE KEY = ?";
private SQLiteDatabase mSQLiteDatabase;
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
public static final String KEY_CIM_SERVIER_HOST = "KEY_CIM_SERVIER_HOST";
public static final String KEY_CIM_SERVIER_PORT = "KEY_CIM_SERVIER_PORT";
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
public synchronized static CIMCacheToolkit getInstance(Context context){
if(toolkit==null){
toolkit = new CIMCacheToolkit(context);
}
return toolkit;
}
public CIMCacheToolkit(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public CIMCacheToolkit(Context context){
this(context, DATABASE_NAME,null, DATABASE_VERSION);
}
public synchronized void remove(String key)
{
getSQLiteDatabase().execSQL(DELETE_SQL,new String[]{key});
}
public synchronized void putString(String key,String value)
{
ContentValues values = new ContentValues();
values.put("VALUE", value);
int result = getSQLiteDatabase().updateWithOnConflict(TABLE_NAME, values, "KEY=?",new String[]{key},SQLiteDatabase.CONFLICT_FAIL);
if(result<=0){
values.put("KEY", key);
getSQLiteDatabase().insert(TABLE_NAME, null, values);
}
}
public synchronized String getString(String key)
{
String value = null;
Cursor cursor = getSQLiteDatabase().rawQuery(QUERY_SQL, new String[]{key});
if (cursor!=null)
{
if(cursor.moveToFirst()){
value = cursor.getString(0);
}
cursor.close();
}
return value;
}
public void putBoolean(String key,boolean value)
{
putString(key,Boolean.toString(value));
}
public boolean getBoolean(String key)
{
String value = getString(key);
return value == null?false:Boolean.parseBoolean(value);
}
public void putInt(String key,int value)
{
putString(key, String.valueOf(value));
}
public int getInt(String key)
{
String value = getString(key);
return value == null?0:Integer.parseInt(value);
}
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(TABLE_SQL);
}
public static synchronized void destroy(){
if (toolkit!=null){
try{toolkit.mSQLiteDatabase.close();}catch(Exception e){}
try{toolkit.close();}catch(Exception e){}
}
toolkit = null;
}
private SQLiteDatabase getSQLiteDatabase(){
if(mSQLiteDatabase!=null){
return mSQLiteDatabase;
}else
{
mSQLiteDatabase = getWritableDatabase();
}
return mSQLiteDatabase;
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -64,22 +65,20 @@ import com.farsunset.cim.sdk.android.model.SentBody;
class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
private final String TAG = CIMConnectorManager.class.getSimpleName();
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int CONNECT_TIMEOUT = 10 * 1000;//
private final int WRITE_TIMEOUT = 10 * 1000;//
private final int READ_IDLE_TIME = 120;//
private final int READ_IDLE_TIME = 120;//
private final int HEARBEAT_TIME_OUT = (READ_IDLE_TIME + 20) * 1000;// 收到服务端心跳请求超时时间 毫秒
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME" ;
private final String KEY_LAST_HEART_TIME = "KEY_LAST_HEART_TIME";
private Bootstrap bootstrap;
private EventLoopGroup loopGroup ;
private EventLoopGroup loopGroup;
private Channel channel;;
private ExecutorService executor = Executors.newFixedThreadPool(1);
private Context context;
private static CIMConnectorManager manager;
private static CIMConnectorManager manager;
private CIMConnectorManager(Context ctx) {
context = ctx;
@ -88,19 +87,19 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
loopGroup = new NioEventLoopGroup();
bootstrap.group(loopGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientMessageDecoder());
ch.pipeline().addLast(new ClientMessageEncoder());
ch.pipeline().addLast(new IdleStateHandler(READ_IDLE_TIME,0,0));
ch.pipeline().addLast(CIMConnectorManager.this);
}
});
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientMessageDecoder());
ch.pipeline().addLast(new ClientMessageEncoder());
ch.pipeline().addLast(new IdleStateHandler(READ_IDLE_TIME, 0, 0));
ch.pipeline().addLast(CIMConnectorManager.this);
}
});
}
@ -112,87 +111,84 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
}
private synchronized void syncConnection( String host, int port) {
if(isConnected()){
return ;
private synchronized void syncConnection(String host, int port) {
if (isConnected()) {
return;
}
try {
Log.i(TAG, "****************CIM正在连接服务器 "+host+":"+port+"......");
ChannelFuture channelFuture = bootstrap.connect(host, port).syncUninterruptibly();
channel = channelFuture.channel();
Log.i(TAG, "****************CIM正在连接服务器 " + host + ":" + port + "......");
ChannelFuture channelFuture = bootstrap.connect(host, port).syncUninterruptibly();
channel = channelFuture.channel();
} catch (Exception e) {
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5*1000 - new Random().nextInt(15*1000));
long interval = CIMConstant.RECONN_INTERVAL_TIME - (5 * 1000 - new Random().nextInt(15 * 1000));
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED);
intent.putExtra(Exception.class.getName(), e.getClass().getSimpleName());
intent.putExtra("interval", interval);
context.sendBroadcast(intent);
Log.e(TAG, "****************CIM连接服务器失败 "+host+":"+port+"......将在"+interval/1000+"秒后重新尝试连接");
}
Log.e(TAG, "****************CIM连接服务器失败 " + host + ":" + port + "......将在" + interval / 1000 + "秒后重新尝试连接");
}
}
public void connect(final String host, final int port) {
if (!isNetworkConnected(context)) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED);
intent.putExtra(Exception.class.getName(), NetworkDisabledException.class.getSimpleName());
context.sendBroadcast(intent);
return;
}
executor.execute(new Runnable() {
public void run()
{
public void run() {
syncConnection(host, port);
}
}
});
}
public synchronized void send(SentBody body) {
boolean isSuccessed = false;
String exceptionName = SessionClosedException.class.getSimpleName();
if(channel!=null && channel.isActive())
{
String exceptionName = SessionClosedException.class.getSimpleName();
if (channel != null && channel.isActive()) {
ChannelFuture future = channel.writeAndFlush(body);
isSuccessed = future.awaitUninterruptibly(WRITE_TIMEOUT);
if(!isSuccessed && future.cause()!=null){
if (!isSuccessed && future.cause() != null) {
exceptionName = future.cause().getClass().getSimpleName();
}
}
if(!isSuccessed){
}
if (!isSuccessed) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_FAILED);
intent.putExtra(Exception.class.getName(),exceptionName);
intent.putExtra(Exception.class.getName(), exceptionName);
intent.putExtra(SentBody.class.getName(), body);
context.sendBroadcast(intent);
}else
{
} else {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED);
intent.putExtra(SentBody.class.getName(), (SentBody) body);
context.sendBroadcast(intent);
}
}
public void destroy() {
public void destroy() {
if (channel != null) {
channel.close();
}
@ -200,7 +196,7 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
if (loopGroup != null) {
loopGroup.shutdownGracefully();
}
manager = null;
}
@ -208,40 +204,35 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
if (channel == null) {
return false;
}
return channel.isActive() ;
return channel.isActive();
}
public void closeSession()
{
if(channel!=null)
{
public void closeSession() {
if (channel != null) {
channel.close();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Log.i(TAG, "****************CIM连接服务器成功:"+ctx.channel().localAddress()+" NID:"+ctx.channel().id().asShortText());
Log.i(TAG, "****************CIM连接服务器成功:" + ctx.channel().localAddress() + " NID:"
+ ctx.channel().id().asShortText());
setLastHeartbeatTime(ctx.channel());
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED);
context.sendBroadcast(intent);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
Log.e(TAG, "****************CIM与服务器断开连接:"+ctx.channel().localAddress()+" NID:"+ctx.channel().id().asShortText());
@Override
public void channelInactive(ChannelHandlerContext ctx) {
Log.e(TAG, "****************CIM与服务器断开连接:" + ctx.channel().localAddress() + " NID:"
+ ctx.channel().id().asShortText());
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
context.sendBroadcast(intent);
@ -249,36 +240,35 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
/**
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件
* 导致这样的情况下当前连接无效也不会重连的问题
* 用于解决wifi情况下偶而路由器与服务器断开连接时客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
*
*/
if (evt instanceof IdleStateEvent && ((IdleStateEvent) evt).state().equals(IdleState.READER_IDLE))
{
Log.d(TAG, "****************CIM "+IdleState.READER_IDLE+":"+ctx.channel().localAddress()+" NID:"+ctx.channel().id().asShortText());
if (evt instanceof IdleStateEvent && ((IdleStateEvent) evt).state().equals(IdleState.READER_IDLE)) {
Log.d(TAG, "****************CIM " + IdleState.READER_IDLE + ":" + ctx.channel().localAddress() + " NID:"
+ ctx.channel().id().asShortText());
Long lastTime = getLastHeartbeatTime(ctx.channel());
if(lastTime != null && System.currentTimeMillis() - lastTime > HEARBEAT_TIME_OUT)
{
channel.close();
Log.e(TAG, "****************CIM心跳超时 ,即将重新连接......"+" NID:"+ctx.channel().id().asShortText());
}
}
if (lastTime != null && System.currentTimeMillis() - lastTime > HEARBEAT_TIME_OUT) {
channel.close();
Log.e(TAG, "****************CIM心跳超时 ,即将重新连接......" + " NID:" + ctx.channel().id().asShortText());
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Log.e(TAG, "****************CIM连接出现未知异常:"+ctx.channel().localAddress()+" NID:"+ctx.channel().id().asShortText());
if(cause!=null && cause.getMessage()!=null){
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Log.e(TAG, "****************CIM连接出现未知异常:" + ctx.channel().localAddress() + " NID:"
+ ctx.channel().id().asShortText());
if (cause != null && cause.getMessage() != null) {
Log.e(TAG, cause.getMessage());
}
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_UNCAUGHT_EXCEPTION);
intent.putExtra(Exception.class.getName(), cause.getClass().getSimpleName());
@ -286,49 +276,48 @@ class CIMConnectorManager extends SimpleChannelInboundHandler<Object> {
}
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception{
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Message) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
intent.putExtra(Message.class.getName(), (Message) msg);
context.sendBroadcast(intent);
}
if (msg instanceof ReplyBody) {
Intent intent = new Intent();
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) msg);
context.sendBroadcast(intent);
}
//收到服务端发来的心跳请求命令则马上回应服务器
// 收到服务端发来的心跳请求命令则马上回应服务器
if (msg instanceof HeartbeatRequest) {
ctx.writeAndFlush(HeartbeatResponse.getInstance());
setLastHeartbeatTime(ctx.channel());
}
}
private void setLastHeartbeatTime(Channel channel)
{
private void setLastHeartbeatTime(Channel channel) {
channel.attr(AttributeKey.valueOf(KEY_LAST_HEART_TIME)).set(System.currentTimeMillis());
}
private Long getLastHeartbeatTime(Channel channel)
{
private Long getLastHeartbeatTime(Channel channel) {
return (Long) channel.attr(AttributeKey.valueOf(KEY_LAST_HEART_TIME)).get();
}
public static boolean isNetworkConnected(Context context) {
try {
ConnectivityManager nw = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = nw.getActiveNetworkInfo();
return networkInfo != null;
} catch (Exception e) {}
} catch (Exception e) {
}
return false;
}
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.android;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
import com.farsunset.cim.sdk.android.exception.SessionClosedException;
import com.farsunset.cim.sdk.android.model.Message;
@ -33,207 +32,185 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
* 消息入口所有消息都会经过这里
* 消息入口所有消息都会经过这里
*/
public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver{
public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
protected Context context;
@Override
public void onReceive(Context ctx, Intent intent) {
context = ctx;
/*
* 操作事件广播用于提高service存活率
*/
if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)
||intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)
||intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED))
{
startPushService();
}
context = ctx;
/*
* 设备网络状态变化事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED))
{
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
onDevicesNetworkChanged(connectivityManager.getActiveNetworkInfo());
}
/*
* cim断开服务器事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED))
{
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED))
{
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
String exceptionName = intent.getStringExtra(Exception.class.getName());
onConnectionFailed(exceptionName,interval);
}
/*
* cim连接服务器成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED))
{
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED))
{
onInnerMessageReceived((Message)intent.getSerializableExtra(Message.class.getName()),intent);
}
/*
* 获取收到replybody成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED))
{
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发送成功事件
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED))
{
onSentSucceed((SentBody)intent.getSerializableExtra(SentBody.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if(intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY))
{
CIMPushManager.connect(context,0);
}
/*
* 操作事件广播用于提高service存活率
*/
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)
|| intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)
|| intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
startPushService();
}
/*
* 设备网络状态变化事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED)) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
onDevicesNetworkChanged(connectivityManager.getActiveNetworkInfo());
}
/*
* cim断开服务器事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED)) {
onInnerConnectionClosed();
}
/*
* cim连接服务器失败事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_FAILED)) {
long interval = intent.getLongExtra("interval", CIMConstant.RECONN_INTERVAL_TIME);
String exceptionName = intent.getStringExtra(Exception.class.getName());
onConnectionFailed(exceptionName, interval);
}
/*
* cim连接服务器成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_SUCCESSED)) {
onInnerConnectionSuccessed();
}
/*
* 收到推送消息事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED)) {
onInnerMessageReceived((Message) intent.getSerializableExtra(Message.class.getName()), intent);
}
/*
* 获取收到replybody成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED)) {
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发送成功事件
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_SENT_SUCCESSED)) {
onSentSucceed((SentBody) intent.getSerializableExtra(SentBody.class.getName()));
}
/*
* 重新连接如果断开的话
*/
if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY)) {
CIMPushManager.connect(context, 0);
}
}
private void startPushService(){
Intent intent = new Intent(context, CIMPushService.class);
private void startPushService() {
Intent intent = new Intent(context, CIMPushService.class);
intent.setAction(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE);
context.startService(intent);
}
private void onInnerConnectionClosed(){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
if(CIMConnectorManager.isNetworkConnected(context))
{
CIMPushManager.connect(context,0);
private void onInnerConnectionClosed() {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
if (CIMConnectorManager.isNetworkConnected(context)) {
CIMPushManager.connect(context, 0);
}
onConnectionClosed();
}
private void onConnectionFailed(String exceptionName,long reinterval){
if(CIMConnectorManager.isNetworkConnected(context))
{
private void onConnectionFailed(String exceptionName, long reinterval) {
if (CIMConnectorManager.isNetworkConnected(context)) {
onConnectionFailed();
CIMPushManager.connect(context,reinterval);
CIMPushManager.connect(context, reinterval);
}
}
private void onInnerConnectionSuccessed(){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
private void onInnerConnectionSuccessed() {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
boolean autoBind = CIMPushManager.autoBindAccount(context);
onConnectionSuccessed(autoBind);
}
private void onDevicesNetworkChanged(NetworkInfo info) {
if(info !=null)
{
CIMPushManager.connect(context,0);
}
private void onDevicesNetworkChanged(NetworkInfo info) {
if (info != null) {
CIMPushManager.connect(context, 0);
}
onNetworkChanged(info);
}
private void onInnerMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent){
if(isForceOfflineMessage(message.getAction()))
{
private void onInnerMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent) {
if (isForceOfflineMessage(message.getAction())) {
CIMPushManager.stop(context);
}
onMessageReceived(message,intent);
}
private boolean isForceOfflineMessage(String 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);
}
onMessageReceived(message, intent);
}
public abstract void onMessageReceived(com.farsunset.cim.sdk.android.model.Message message,Intent intent);
public void onNetworkChanged(NetworkInfo info) {
private boolean isForceOfflineMessage(String 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 void onNetworkChanged(NetworkInfo info) {
CIMListenerManager.notifyOnNetworkChanged(info);
}
public void onConnectionSuccessed(boolean hasAutoBind) {
public void onConnectionSuccessed(boolean hasAutoBind) {
CIMListenerManager.notifyOnConnectionSuccessed(hasAutoBind);
}
public void onConnectionClosed() {
public void onConnectionClosed() {
CIMListenerManager.notifyOnConnectionClosed();
}
public void onConnectionFailed() {
public void onConnectionFailed() {
CIMListenerManager.notifyOnConnectionFailed();
}
public void onReplyReceived(ReplyBody body) {
public void onReplyReceived(ReplyBody body) {
CIMListenerManager.notifyOnReplyReceived(body);
}
public void onSentSucceed(SentBody body){
public void onSentSucceed(SentBody body) {
CIMListenerManager.notifyOnSentSucceed(body);
}
}

View File

@ -28,59 +28,60 @@ import com.farsunset.cim.sdk.android.model.ReplyBody;
import com.farsunset.cim.sdk.android.model.SentBody;
/**
*CIM 主要事件接口
* CIM 主要事件接口
*/
public interface CIMEventListener
{
public interface CIMEventListener {
/**
* 当收到服务端推送过来的消息时调用
*
* @param message
*/
void onMessageReceived(Message message);
/**
* 当收到服务端推送过来的消息时调用
* @param message
*/
void onMessageReceived(Message message);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
*
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求获得相应时调用
* @param replybody
*/
void onReplyReceived(ReplyBody replybody);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
*
* @param body
*/
void onSentSuccessed(SentBody body);
/**
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
* @param body
*/
void onSentSuccessed(SentBody body);
/**
* 当手机网络发生变化时调用
*
* @param networkinfo
*/
void onNetworkChanged(NetworkInfo networkinfo);
/**
* 当手机网络发生变化时调用
* @param networkinfo
*/
void onNetworkChanged(NetworkInfo networkinfo);
/**
* 当连接服务器成功时回调
* @param hasAutoBind : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当断开服务器连接的时候回调
*
*/
void onConnectionClosed();
/**
* 当连接服务器失败的时候回调
*
*/
void onConnectionFailed();
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
/**
* 当连接服务器成功时回调
*
* @param hasAutoBind
* : true 已经自动绑定账号到服务器了不需要再手动调用bindAccount
*/
void onConnectionSuccessed(boolean hasAutoBind);
/**
* 当断开服务器连接的时候回调
*
*/
void onConnectionClosed();
/**
* 当连接服务器失败的时候回调
*
*/
void onConnectionFailed();
/**
* 监听器在容器里面的排序值越大则越先接收
*/
int getEventDispatchOrder();
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -30,25 +31,23 @@ import com.farsunset.cim.sdk.android.model.SentBody;
import android.net.NetworkInfo;
import android.util.Log;
/**
* CIM 消息监听器管理
*/
public class CIMListenerManager {
public class CIMListenerManager {
private static ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
private static CIMMessageReceiveComparator comparator = new CIMMessageReceiveComparator();
public static void registerMessageListener(CIMEventListener listener) {
if (!cimListeners.contains(listener)) {
cimListeners.add(listener);
Collections.sort(cimListeners,comparator);
Collections.sort(cimListeners, comparator);
}
}
public static void removeMessageListener(CIMEventListener listener) {
for (int i = 0; i < cimListeners.size(); i++) {
if (listener.getClass() == cimListeners.get(i).getClass()) {
@ -56,76 +55,72 @@ public class CIMListenerManager {
}
}
}
public static void notifyOnNetworkChanged(NetworkInfo info) {
for (CIMEventListener listener : cimListeners) {
listener.onNetworkChanged(info);
}
}
public static void notifyOnConnectionSuccessed(boolean hasAutoBind) {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionSuccessed(hasAutoBind);
}
}
public static void notifyOnMessageReceived(Message message) {
for (CIMEventListener listener : cimListeners) {
listener.onMessageReceived(message);
}
}
public static void notifyOnConnectionClosed() {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionClosed();
}
}
public static void notifyOnConnectionFailed() {
for (CIMEventListener listener : cimListeners) {
listener.onConnectionFailed();
}
}
public static void notifyOnReplyReceived(ReplyBody body) {
for (CIMEventListener listener : cimListeners) {
listener.onReplyReceived(body);
}
}
public static void notifyOnSentSucceed(SentBody body) {
for (CIMEventListener listener : cimListeners) {
listener.onSentSuccessed(body);
}
}
public static void destory() {
cimListeners.clear();
}
public static void logListenersName() {
for (CIMEventListener listener : cimListeners) {
Log.i(CIMEventListener.class.getSimpleName(),"#######" + listener.getClass().getName() + "#######" );
Log.i(CIMEventListener.class.getSimpleName(), "#######" + listener.getClass().getName() + "#######");
}
}
/**
* 消息接收activity的接收顺序排序CIM_RECEIVE_ORDER倒序
*/
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener>{
private static class CIMMessageReceiveComparator implements Comparator<CIMEventListener> {
@Override
public int compare(CIMEventListener arg1, CIMEventListener arg2) {
int order1 = arg1.getEventDispatchOrder();
int order2 = arg2.getEventDispatchOrder();
return order2 - order1 ;
return order2 - order1;
}
}
}

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import java.util.UUID;
import android.content.Context;
@ -34,212 +35,204 @@ import com.farsunset.cim.sdk.android.model.SentBody;
/**
* CIM 功能接口
*/
public class CIMPushManager {
public class CIMPushManager {
static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY = "ACTION_DESTORY";
static String KEY_SEND_BODY = "KEY_SEND_BODY";
static String KEY_CIM_CONNECTION_STATUS = "KEY_CIM_CONNECTION_STATUS";
static String ACTION_ACTIVATE_PUSH_SERVICE ="ACTION_ACTIVATE_PUSH_SERVICE";
static String ACTION_CREATE_CIM_CONNECTION ="ACTION_CREATE_CIM_CONNECTION";
static String ACTION_SEND_REQUEST_BODY ="ACTION_SEND_REQUEST_BODY";
static String ACTION_CLOSE_CIM_CONNECTION ="ACTION_CLOSE_CIM_CONNECTION";
static String ACTION_DESTORY ="ACTION_DESTORY";
static String KEY_SEND_BODY ="KEY_SEND_BODY";
static String KEY_CIM_CONNECTION_STATUS ="KEY_CIM_CONNECTION_STATUS";
/**
* 初始化,连接服务端在程序启动页或者 在Application里调用
*
* @param context
* @param ip
* @param port
*/
public static void connect(Context context,String host,int port){
connect(context,host,port,false,0);
}
private static void connect(Context context,String ip,int port,boolean autoBind,long delayedTime){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED, false);
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, false);
public static void connect(Context context, String host, int port) {
connect(context, host, port, false, 0);
}
private static void connect(Context context, String ip, int port, boolean autoBind, long delayedTime) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false);
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
CIMCacheManager.putInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
if(!autoBind)
{
CIMCacheManager.remove(context,CIMCacheManager.KEY_ACCOUNT);
if (!autoBind) {
CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT);
}
Intent serviceIntent = new Intent(context, CIMPushService.class);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST, ip);
serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, port);
serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delayedTime);
serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION);
context.startService(serviceIntent);
}
protected static void connect(Context context,long delayedTime){
boolean isManualStop = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
}
protected static void connect(Context context, long delayedTime) {
boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
String host = CIMCacheManager.getString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port =CIMCacheManager.getInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT);
connect(context,host,port,true,delayedTime);
}
int port = CIMCacheManager.getInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT);
connect(context, host, port, true, delayedTime);
}
/**
* 设置一个账号登录到服务端
* @param account 用户唯一ID
*
* @param account
* 用户唯一ID
*/
public static void bindAccount(Context context,String account){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory || account==null || account.trim().length()==0)
{
return ;
}
sendBindRequest(context,account);
}
private static void sendBindRequest(Context context, String account){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context,CIMCacheManager.KEY_ACCOUNT, account);
String deviceId = CIMCacheManager.getString(context,CIMCacheManager.KEY_DEVICE_ID);
if(TextUtils.isEmpty(deviceId)) {
deviceId = UUID.randomUUID().toString().replaceAll("-", "");
CIMCacheManager.putString(context,CIMCacheManager.KEY_DEVICE_ID, deviceId);
}
public static void bindAccount(Context context, String account) {
SentBody sent = new SentBody();
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory || account == null || account.trim().length() == 0) {
return;
}
sendBindRequest(context, account);
}
private static void sendBindRequest(Context context, String account) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, account);
String deviceId = CIMCacheManager.getString(context, CIMCacheManager.KEY_DEVICE_ID);
if (TextUtils.isEmpty(deviceId)) {
deviceId = UUID.randomUUID().toString().replaceAll("-", "");
CIMCacheManager.putString(context, CIMCacheManager.KEY_DEVICE_ID, deviceId);
}
SentBody sent = new SentBody();
sent.setKey(CIMConstant.RequestKey.CLIENT_BIND);
sent.put("account", account);
sent.put("deviceId",deviceId);
sent.put("deviceId", deviceId);
sent.put("channel", "android");
sent.put("device",android.os.Build.MODEL);
sent.put("version",getVersionName(context));
sent.put("osVersion",android.os.Build.VERSION.RELEASE);
sent.put("packageName",context.getPackageName());
sendRequest(context,sent);
}
protected static boolean autoBindAccount(Context context){
String account = CIMCacheManager.getString(context,CIMCacheManager.KEY_ACCOUNT);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if( account==null || account.trim().length()==0 || isManualDestory )
{
return false;
}
sendBindRequest(context,account);
return true;
sent.put("device", android.os.Build.MODEL);
sent.put("version", getVersionName(context));
sent.put("osVersion", android.os.Build.VERSION.RELEASE);
sent.put("packageName", context.getPackageName());
sendRequest(context, sent);
}
protected static boolean autoBindAccount(Context context) {
/**
String account = CIMCacheManager.getString(context, CIMCacheManager.KEY_ACCOUNT);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (account == null || account.trim().length() == 0 || isManualDestory) {
return false;
}
sendBindRequest(context, account);
return true;
}
/**
* 发送一个CIM请求
*
* @param context
* @body
*/
public static void sendRequest(Context context, SentBody body){
boolean isManualStop = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualStop || isManualDestory)
{
return ;
public static void sendRequest(Context context, SentBody body) {
boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualStop || isManualDestory) {
return;
}
Intent serviceIntent = new Intent(context, CIMPushService.class);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.putExtra(KEY_SEND_BODY, body);
serviceIntent.setAction(ACTION_SEND_REQUEST_BODY);
context.startService(serviceIntent);
}
/**
/**
* 停止接受推送将会退出当前账号登录端口与服务端的连接
*
* @param context
*/
public static void stop(Context context){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_MANUAL_STOP, true);
public static void stop(Context context) {
Intent serviceIntent = new Intent(context, CIMPushService.class);
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, true);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION);
context.startService(serviceIntent);
}
/**
/**
* 完全销毁CIM一般用于完全退出程序调用resume将不能恢复
*
* @param context
*/
public static void destroy(Context context){
CIMCacheManager.putBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED, true);
CIMCacheManager.putString(context,CIMCacheManager.KEY_ACCOUNT, null);
Intent serviceIntent = new Intent(context, CIMPushService.class);
public static void destroy(Context context) {
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, true);
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, null);
Intent serviceIntent = new Intent(context, CIMPushService.class);
serviceIntent.setAction(ACTION_DESTORY);
context.startService(serviceIntent);
}
/**
* 重新恢复接收推送重新连接服务端并登录当前账号
* @param context
*/
public static void resume(Context context){
boolean isManualDestory = CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_DESTROYED);
if(isManualDestory){
return ;
}
autoBindAccount(context);
/**
* 重新恢复接收推送重新连接服务端并登录当前账号
*
* @param context
*/
public static void resume(Context context) {
boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
if (isManualDestory) {
return;
}
autoBindAccount(context);
}
public static boolean isConnected(Context context){
return CIMCacheManager.getBoolean(context,CIMCacheManager.KEY_CIM_CONNECTION_STATE);
}
private static String getVersionName(Context context) {
String versionName = null;
public static boolean isConnected(Context context) {
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE);
}
private static String getVersionName(Context context) {
String versionName = null;
try {
PackageInfo mPackageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
versionName = mPackageInfo.versionName;

View File

@ -20,6 +20,7 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
@ -28,98 +29,88 @@ import android.os.Message;
import android.util.Log;
import com.farsunset.cim.sdk.android.model.SentBody;
/**
* 与服务端连接服务
*
* @author 3979434
*
*/
public class CIMPushService extends Service {
private final String TAG = CIMPushService.class.getSimpleName();
public final static String KEY_DELAYED_TIME ="KEY_DELAYED_TIME";
public class CIMPushService extends Service {
private final String TAG = CIMPushService.class.getSimpleName();
public final static String KEY_DELAYED_TIME = "KEY_DELAYED_TIME";
private CIMConnectorManager manager;
@Override
public void onCreate()
{
manager = CIMConnectorManager.getManager(this.getApplicationContext());
}
Handler connectionHandler = new Handler(){
@Override
public void onCreate() {
manager = CIMConnectorManager.getManager(this.getApplicationContext());
}
Handler connectionHandler = new Handler() {
@Override
public void handleMessage(android.os.Message message){
public void handleMessage(android.os.Message message) {
connectionHandler.removeMessages(0);
String host = message.getData().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = message.getData().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT,0);
int port = message.getData().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0);
manager.connect(host, port);
}
};
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if(CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action))
{
long delayMillis = intent.getLongExtra(KEY_DELAYED_TIME,0);
if( delayMillis > 0){
Message msg = connectionHandler.obtainMessage();
msg.what = 0;
msg.setData(intent.getExtras());
connectionHandler.sendMessageDelayed(msg, delayMillis);
}else
{
String host = intent.getStringExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = intent.getIntExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT,0);
manager.connect(host,port);
}
}
if(CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action))
{
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
}
if(CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action))
{
manager.closeSession();
}
if(CIMPushManager.ACTION_DESTORY.equals(action))
{
manager.destroy();
this.stopSelf();
}
if(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action) )
{
if(!manager.isConnected()){
boolean isManualStop = CIMCacheManager.getBoolean(getApplicationContext(),CIMCacheManager.KEY_MANUAL_STOP);
Log.w(TAG, "manager.isConnected() == false, isManualStop == " + isManualStop);
CIMPushManager.connect(this,0);
}else
{
Log.i(TAG, "manager.isConnected() == true");
}
}
return START_STICKY;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent);
String action = intent.getAction();
if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) {
long delayMillis = intent.getLongExtra(KEY_DELAYED_TIME, 0);
if (delayMillis > 0) {
Message msg = connectionHandler.obtainMessage();
msg.what = 0;
msg.setData(intent.getExtras());
connectionHandler.sendMessageDelayed(msg, delayMillis);
} else {
String host = intent.getStringExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST);
int port = intent.getIntExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0);
manager.connect(host, port);
}
}
if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) {
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
}
if (CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action)) {
manager.closeSession();
}
if (CIMPushManager.ACTION_DESTORY.equals(action)) {
manager.destroy();
this.stopSelf();
}
if (CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action)) {
if (!manager.isConnected()) {
boolean isManualStop = CIMCacheManager.getBoolean(getApplicationContext(),
CIMCacheManager.KEY_MANUAL_STOP);
Log.w(TAG, "manager.isConnected() == false, isManualStop == " + isManualStop);
CIMPushManager.connect(this, 0);
} else {
Log.i(TAG, "manager.isConnected() == true");
}
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return null;

View File

@ -21,93 +21,88 @@
*/
package com.farsunset.cim.sdk.android.constant;
/**
/**
* 常量
*/
public interface CIMConstant {
long RECONN_INTERVAL_TIME= 30 * 1000;
//消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
public interface CIMConstant {
long RECONN_INTERVAL_TIME = 30 * 1000;
// 消息头长度为3个字节第一个字节为消息类型第二第三字节 转换int后为消息长度
int DATA_HEADER_LENGTH = 3;
public static interface ReturnCode{
String CODE_404 ="404";
String CODE_403 ="403";
String CODE_405 ="405";
String CODE_200 ="200";
String CODE_206 ="206";
String CODE_500 ="500";
public static interface ReturnCode {
String CODE_404 = "404";
String CODE_403 = "403";
String CODE_405 = "405";
String CODE_200 = "200";
String CODE_206 = "206";
String CODE_500 = "500";
}
public static interface ProtobufType {
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey {
String CLIENT_BIND = "client_bind";
String CLIENT_LOGOUT = "client_logout";
public static interface ProtobufType{
byte C_H_RS = 0;
byte S_H_RQ = 1;
byte MESSAGE = 2;
byte SENTBODY = 3;
byte REPLYBODY = 4;
}
public static interface RequestKey{
String CLIENT_BIND ="client_bind";
String CLIENT_LOGOUT ="client_logout";
@Deprecated
String CLIENT_PULL_MESSAGE ="client_pull_message";
String CLIENT_PULL_MESSAGE = "client_pull_message";
}
public static interface MessageAction{
//被其他设备登录挤下线消息
String ACTION_999 ="999";
}
public static interface IntentAction{
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
//重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
// 未知异常
String ACTION_UNCAUGHT_EXCEPTION = "com.farsunset.cim.UNCAUGHT_EXCEPTION";
}
public static interface MessageAction {
// 被其他设备登录挤下线消息
String ACTION_999 = "999";
}
public static interface IntentAction {
// 消息广播action
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
// 发送sendbody失败广播
String ACTION_SENT_FAILED = "com.farsunset.cim.SENT_FAILED";
// 发送sendbody成功广播
String ACTION_SENT_SUCCESSED = "com.farsunset.cim.SENT_SUCCESSED";
// 链接意外关闭广播
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
// 链接失败广播
String ACTION_CONNECTION_FAILED = "com.farsunset.cim.CONNECTION_FAILED";
// 链接成功广播
String ACTION_CONNECTION_SUCCESSED = "com.farsunset.cim.CONNECTION_SUCCESSED";
// 发送sendbody成功后获得replaybody回应广播
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
// 网络变化广播
String ACTION_NETWORK_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
// 重试连接
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
// 未知异常
String ACTION_UNCAUGHT_EXCEPTION = "com.farsunset.cim.UNCAUGHT_EXCEPTION";
}
}

View File

@ -23,14 +23,14 @@ package com.farsunset.cim.sdk.android.exception;
import java.io.Serializable;
public class NetworkDisabledException extends Exception implements Serializable {
public class NetworkDisabledException extends Exception implements Serializable {
private static final long serialVersionUID = 1L;
public NetworkDisabledException() {
super();
}
public NetworkDisabledException(String s) {
super(s);
}

View File

@ -24,7 +24,7 @@ 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() {

View File

@ -41,6 +41,7 @@ import io.netty.handler.codec.ByteToMessageDecoder;
*/
public class ClientMessageDecoder extends ByteToMessageDecoder {
final static String TAG = ClientMessageDecoder.class.getSimpleName();
@Override
protected void decode(ChannelHandlerContext arg0, ByteBuf buffer, List<Object> queue) throws Exception {
@ -72,8 +73,8 @@ public class ClientMessageDecoder extends ByteToMessageDecoder {
buffer.readBytes(dataBytes);
Object message = mappingMessageObject(dataBytes, conetnType);
if(message!=null){
if (message != null) {
queue.add(message);
}

View File

@ -21,7 +21,6 @@
*/
package com.farsunset.cim.sdk.android.filter;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
import com.farsunset.cim.sdk.android.model.Protobufable;
@ -31,46 +30,41 @@ import io.netty.handler.codec.MessageToByteEncoder;
import android.util.Log;
/**
* 客户端消息发送前进行编码,可在此加密消息
* 客户端消息发送前进行编码,可在此加密消息
*
*/
public class ClientMessageEncoder extends MessageToByteEncoder<Object> {
public class ClientMessageEncoder extends MessageToByteEncoder<Object> {
@Override
protected void encode(ChannelHandlerContext ctx, Object message, ByteBuf out) throws Exception {
if(message instanceof Protobufable){
Protobufable data = (Protobufable) message;
byte[] byteArray = data.getByteArray();
out.writeBytes(createHeader(data.getType(),byteArray.length));
out.writeBytes(byteArray);
}
if (message instanceof Protobufable) {
Protobufable data = (Protobufable) message;
byte[] byteArray = data.getByteArray();
out.writeBytes(createHeader(data.getType(), byteArray.length));
out.writeBytes(byteArray);
}
Log.i(ClientMessageEncoder.class.getSimpleName(), message.toString());
}
/**
* 消息体最大为65535
*
* @param type
* @param length
* @return
*/
private byte[] createHeader(byte type,int length){
private byte[] createHeader(byte type, int length) {
byte[] header = new byte[CIMConstant.DATA_HEADER_LENGTH];
header[0] = type;
header[1] = (byte) (length & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
header[2] = (byte) ((length >> 8) & 0xff);
return header;
}
}

View File

@ -24,39 +24,39 @@ package com.farsunset.cim.sdk.android.model;
import java.io.Serializable;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
/**
* 服务端心跳请求
*
*/
public class HeartbeatRequest implements Serializable,Protobufable {
public class HeartbeatRequest implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
private static final String CMD_HEARTBEAT_RESPONSE = "SR";
private static HeartbeatRequest object = new HeartbeatRequest();
private HeartbeatRequest(){
private HeartbeatRequest() {
}
public static HeartbeatRequest getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@Override
public byte getType() {
return CIMConstant.ProtobufType.S_H_RQ;
}
}

View File

@ -24,30 +24,32 @@ package com.farsunset.cim.sdk.android.model;
import java.io.Serializable;
import com.farsunset.cim.sdk.android.constant.CIMConstant;
/**
* 客户端心跳响应
*/
public class HeartbeatResponse implements Serializable,Protobufable {
public class HeartbeatResponse implements Serializable, Protobufable {
private static final long serialVersionUID = 1L;
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse(){
private static HeartbeatResponse object = new HeartbeatResponse();
private HeartbeatResponse() {
}
public static HeartbeatResponse getInstance() {
return object;
}
@Override
public byte[] getByteArray() {
return CMD_HEARTBEAT_RESPONSE.getBytes();
}
public String toString(){
public String toString() {
return TAG;
}
@ -55,5 +57,5 @@ public class HeartbeatResponse implements Serializable,Protobufable {
public byte getType() {
return CIMConstant.ProtobufType.C_H_RS;
}
}

View File

@ -30,13 +30,11 @@ public class Message implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 消息类型用户自定义消息类别
*/
private String mid;
/**
* 消息类型用户自定义消息类别
*/
@ -59,8 +57,6 @@ public class Message implements Serializable {
*/
private String receiver;
/**
* content 内容格式
*/
@ -72,12 +68,11 @@ public class Message implements Serializable {
private String extra;
private long timestamp;
public Message()
{
public Message() {
timestamp = System.currentTimeMillis();
}
public long getTimestamp() {
return timestamp;
}
@ -86,14 +81,14 @@ public class Message implements Serializable {
this.timestamp = timestamp;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTitle() {
return title;
}
@ -126,7 +121,6 @@ public class Message implements Serializable {
this.receiver = receiver;
}
public String getFormat() {
return format;
}
@ -134,17 +128,17 @@ public class Message implements Serializable {
public void setFormat(String format) {
this.format = format;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("#Message#").append("\n");
buffer.append("mid:").append(mid).append("\n");
@ -158,7 +152,6 @@ public class Message implements Serializable {
buffer.append("timestamp:").append(timestamp);
return buffer.toString();
}
public String getMid() {
return mid;
@ -169,8 +162,7 @@ public class Message implements Serializable {
}
public boolean isNotEmpty(String txt) {
return txt != null && txt.trim().length()!=0;
return txt != null && txt.trim().length() != 0;
}
}

View File

@ -20,12 +20,13 @@
***************************************************************************************
*/
package com.farsunset.cim.sdk.android.model;
/**
* 需要向另一端发送的结构体
*/
public interface Protobufable {
byte[] getByteArray();
byte getType();
}

Some files were not shown because too many files have changed in this diff Show More