开场白:squareup大法好啊
9月2号更新:
接收到message,如果用户在其他界面,我们可以使用 Notification给它更好的提醒。
NotifacationManagerUtils:
主要作用:
1.控制声音,控制震动
2.使用Rxjava2 控制短时间大量发送消息优化。
3.同一个人进入消息详情设置setChatUid,就可以屏蔽不在继续弹该ChatUid的用户消息。
8月22号更新:
起因:类似于假链接的意思(服务器认为你断开,客户端实际链接上。其他这里面有很多因素,具体需要自己去排除)
解决办法:
客户端与服务端指定一套规则:模拟WebSocket ping pong 动作,客户端 x分钟 通过WebSocket给服务器发送一次ping,服务器回复pong。如果x秒后接收到,就说明链接上了。如果x秒后没有接收到,并且自己认为自己是链接状态 那就断开重新链接。
——————————————————————————–分割线——————————————————-
简述:关于一些推送和IM 功能,可能大家都采用的是第三方(环信,融云 极光等)
但是我们由于这一块的业务目前还是特别大,就自己搭建了聊天和推送系统。
代码中如果有不足的地方,可以相互讨论一下,提供一个我在实际项目中,所遇到困难,解决的思路。
利与弊:
利:
- 第三方 集成简单,方便使用,持续有团队优化。
- 自己搭建 扩展性高,数据 安全性比较高(提升到https)
弊:
- 第三方数据相比自己搭建安全性差一些,所有数据都经过第三方。
- 自己搭建开发周期时间长,而且所用到技术需要经过严格测试并且加入特殊异常处理机制, 扩展功能比较麻烦(因为支持功能设计前后端的设计)。
WebSocket设计思路:
- 参数初始化(断线重连次数,连接状态)
- 连接服务器设置。
- 连接WebSocket。
- 定时器查看连接状态 // 定时器实现可以搜索google
WebSocket 使用方法:
ChatController.getInstance().startConnection(mcontext);
可以查看下面具体实现。
WebSocket 源码(持续优化)
/**
* 作者:taolipeng
* 邮箱:15921216945@163.com
*
*/
public class ChatController {
public static final int connecttimeout = 1 * 1000;
private Context mContext;
public ChatController() {
initConnection();
}
private void initConnection() {
Log.d("WebSocket", "初始化");
ResetRetry();
setConnected(false);
initServerUri();
WebSocketInit();
}
private void initServerUri() {
serverUri = "ws:ip:port" // 如: ws:192.168.0.1:80
}
private void closeWebScoket() {
if (mWebSocket == null) return;
mWebSocket.close(1000, null);
}
/**
* 重试机制
* 2*n n = 1—5
* <p>
* 服务器异常情况下,链接超过五次。就不链接了
*/
private int RetryCount = 1;
private int RetrySecondTime = 0; // 秒
private boolean ErrorConnection = false;
private void retryConnection() {
RetrySecondTime = RetryCount * 2;
RetryCount++;
LogUtil.d("retryConnection", "retryConnection RetryCount =" + RetryCount);
if (RetryCount == 5) {
// WebSocket 在下一次进入 或者 成功链接
ErrorConnection = true;
return;
}
try {
RxTimerUtils.cancel();
RxTimerUtils.timer(RetrySecondTime, new RxTimerUtils.IRxNext() {
@Override
public void doNext(long number) {
}
@Override
public void complete() {
// 重新链接
BindBackstageWebSocketRule();
}
});
} catch (Exception e) {
}
}
// 重置重试机制
private void ResetRetry() {
RetryCount = 1;
RetrySecondTime = 0;
ErrorConnection = false;
}
private void WebSocketReceive(String message) {
LogUtil.e(debug, TAG, "获取到服务器信息---scoket【" + message + "】");
setConnected(true);
// 界面刷新传递。
if("pong".equals(message)){
//收到特定消息
ConnectionRealAlive = true;
}else if("letter".equals(message)){
// Notification 提醒
NotifacationManagerUtils.getIstance().ChatnotifyToBrand(mContext, type, msgItemsEntity)
//接收到信息,处理逻辑。
}
}
@NonNull
public static byte[] lock = new byte[0];
private static ChatController mWbController;
WebSocketListener socketListener;
boolean connected = false;
public boolean isConnected() {
return connected;
}
public void setConnected(boolean connected) {
this.connected = connected;
}
// 实际根据业务来
protected static String getToken() {
return "服务设置Token";
}
public static ChatController