Commit 58077cdf authored by sheteng's avatar sheteng

socket框架切换成netty

parent ad44c82d
...@@ -61,6 +61,6 @@ dependencies { ...@@ -61,6 +61,6 @@ dependencies {
implementation 'com.google.protobuf:protobuf-java:3.13.0' implementation 'com.google.protobuf:protobuf-java:3.13.0'
implementation 'com.google.protobuf:protobuf-java-util:3.12.0' implementation 'com.google.protobuf:protobuf-java-util:3.12.0'
implementation 'com.guolindev.permissionx:permissionx:1.6.1' implementation 'com.guolindev.permissionx:permissionx:1.6.1'
implementation 'com.tonystark.android:socket:latest.release' implementation 'io.netty:netty-all:4.1.4.Final'
implementation 'com.tonystark.android:socket-server:latest.release'
} }
\ No newline at end of file
package com.ccwangluo.im.data; package com.ccwangluo.im.data;
import android.content.Context;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
...@@ -26,7 +28,7 @@ public class LoginViewModel extends ViewModel { ...@@ -26,7 +28,7 @@ public class LoginViewModel extends ViewModel {
public MutableLiveData<List<Long>> channelList = new MutableLiveData<>(); public MutableLiveData<List<Long>> channelList = new MutableLiveData<>();
public void login(String appKey, String appsecret, String username, String userId, String ip, int port) { public void login(Context context, String appKey, String appsecret, String username, String userId, String ip, int port) {
Long id = Long.parseLong(userId); Long id = Long.parseLong(userId);
String extData = "extData"; String extData = "extData";
Long ts = System.currentTimeMillis(); Long ts = System.currentTimeMillis();
...@@ -35,7 +37,7 @@ public class LoginViewModel extends ViewModel { ...@@ -35,7 +37,7 @@ public class LoginViewModel extends ViewModel {
//sign计算在服务器,本地不要暴露appsecrect //sign计算在服务器,本地不要暴露appsecrect
String sign = HmacUtil.stringToSign(appsecret, data); String sign = HmacUtil.stringToSign(appsecret, data);
CCIMClient.getInstance().initServer(ip, port); CCIMClient.getInstance().initServer(ip, port);
CCIMClient.getInstance().initSDK(appKey, username, extData, id, ts, sign, new OnConnectListener() { CCIMClient.getInstance().initSDK(context,appKey, username, extData, id, ts, sign, new OnConnectListener() {
@Override @Override
public void onSocketConnection() { public void onSocketConnection() {
loginState.postValue(true); loginState.postValue(true);
......
...@@ -2,6 +2,7 @@ package com.ccwangluo.im.ui.dashboard; ...@@ -2,6 +2,7 @@ package com.ccwangluo.im.ui.dashboard;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
...@@ -14,6 +15,7 @@ import com.ccwangluo.ccim.CCIMClient; ...@@ -14,6 +15,7 @@ import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.Contact; import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.PushPrivateMsgRes; import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.ccim.listener.ResultCallback; import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.ccim.util.MediaHelper;
import com.ccwangluo.im.adapter.PrivateMsgAdapter; import com.ccwangluo.im.adapter.PrivateMsgAdapter;
import com.ccwangluo.im.data.LoginViewModel; import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentConnectBinding; import com.ccwangluo.im.databinding.FragmentConnectBinding;
...@@ -26,7 +28,7 @@ public class ConnectFragment extends Fragment { ...@@ -26,7 +28,7 @@ public class ConnectFragment extends Fragment {
private LoginViewModel loginViewModel; private LoginViewModel loginViewModel;
private PrivateMsgAdapter privaetMsgAdapter; private PrivateMsgAdapter privaetMsgAdapter;
private List<PushPrivateMsgRes.MessageDTO> list = new ArrayList<>(); private List<PushPrivateMsgRes.MessageDTO> list = new ArrayList<>();
private String filePath;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
...@@ -79,6 +81,27 @@ public class ConnectFragment extends Fragment { ...@@ -79,6 +81,27 @@ public class ConnectFragment extends Fragment {
}); });
} }
}); });
binding.sendVoice.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
CCIMClient.getInstance().stopAndSendAudioMessage();
}
if(event.getAction() == MotionEvent.ACTION_DOWN){
CCIMClient.getInstance().startRecordAudioMessage(getActivity());
}
return false;
}
});
binding.playVoice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CCIMClient.getInstance().startPlayAudio(MediaHelper.getInstance().getFilePath());
}
});
return binding.getRoot(); return binding.getRoot();
} }
} }
\ No newline at end of file
...@@ -54,8 +54,8 @@ public class ContactsFragment extends Fragment { ...@@ -54,8 +54,8 @@ public class ContactsFragment extends Fragment {
@Override @Override
public void onClick(Contact contact) { public void onClick(Contact contact) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable("contact",contact); bundle.putSerializable("contact", contact);
navController.navigate(R.id.navigation_connect,bundle); navController.navigate(R.id.navigation_connect, bundle);
} }
}); });
...@@ -66,7 +66,7 @@ public class ContactsFragment extends Fragment { ...@@ -66,7 +66,7 @@ public class ContactsFragment extends Fragment {
public void onChanged(Collection<Contact> contacts) { public void onChanged(Collection<Contact> contacts) {
contactList.clear(); contactList.clear();
contactList.addAll(contacts); contactList.addAll(contacts);
contactExpandableAdapter.reFreshData(contactGroupList,contactList); contactExpandableAdapter.reFreshData(contactGroupList, contactList);
} }
}); });
...@@ -75,7 +75,7 @@ public class ContactsFragment extends Fragment { ...@@ -75,7 +75,7 @@ public class ContactsFragment extends Fragment {
public void onChanged(Collection<ContactGroup> contactGroups) { public void onChanged(Collection<ContactGroup> contactGroups) {
contactGroupList.clear(); contactGroupList.clear();
contactGroupList.addAll(contactGroups); contactGroupList.addAll(contactGroups);
contactExpandableAdapter.reFreshData(contactGroupList,contactList); contactExpandableAdapter.reFreshData(contactGroupList, contactList);
} }
}); });
...@@ -94,7 +94,7 @@ public class ContactsFragment extends Fragment { ...@@ -94,7 +94,7 @@ public class ContactsFragment extends Fragment {
CCIMClient.getInstance().searchUser(userName, new ResultEventCallback<List<User>>() { CCIMClient.getInstance().searchUser(userName, new ResultEventCallback<List<User>>() {
@Override @Override
public void onSuccess(List<User> users) { public void onSuccess(List<User> users) {
if (users.size() > 0) { if (users != null && users.size() > 0) {
showSearchResultdialog(users); showSearchResultdialog(users);
} }
} }
...@@ -126,7 +126,7 @@ public class ContactsFragment extends Fragment { ...@@ -126,7 +126,7 @@ public class ContactsFragment extends Fragment {
CCIMClient.getInstance().createContactGroup(groupname, new ResultEventCallback<Long>() { CCIMClient.getInstance().createContactGroup(groupname, new ResultEventCallback<Long>() {
@Override @Override
public void onSuccess(Long aLong) { public void onSuccess(Long aLong) {
Toast.makeText(getContext(),"createContactGroup success",Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "createContactGroup success", Toast.LENGTH_SHORT).show();
loginViewModel.getContactList(); loginViewModel.getContactList();
} }
}); });
......
...@@ -66,7 +66,7 @@ public class LoginActivity extends AppCompatActivity { ...@@ -66,7 +66,7 @@ public class LoginActivity extends AppCompatActivity {
String appSecret = binding.appSecret.getText().toString(); String appSecret = binding.appSecret.getText().toString();
String ip = binding.ip.getText().toString(); String ip = binding.ip.getText().toString();
int port = Integer.parseInt(binding.port.getText().toString()); int port = Integer.parseInt(binding.port.getText().toString());
loginViewModel.login(appkey,appSecret,username, id,ip,port); loginViewModel.login(LoginActivity.this,appkey,appSecret,username, id,ip,port);
} }
}); });
} }
......
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity2"> tools:context=".MainActivity2">
<ListView <ListView
android:id="@+id/msg_list" android:id="@+id/msg_list"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -17,21 +18,44 @@ ...@@ -17,21 +18,44 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="100dp" android:layout_marginBottom="10dp"
android:orientation="horizontal"> android:orientation="horizontal">
<EditText <EditText
android:id="@+id/send_edit" android:id="@+id/send_edit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_weight="1" android:layout_height="wrap_content"
android:layout_height="wrap_content"/> android:layout_weight="1" />
<Button <Button
android:id="@+id/send_btn" android:id="@+id/send_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Button" /> android:text="发送文字" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:layout_marginBottom="100dp"
android:orientation="horizontal">
<Button
android:id="@+id/send_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="语音" />
<Button
android:layout_marginLeft="10dp"
android:id="@+id/play_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="播放" />
</LinearLayout>
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -62,8 +62,9 @@ dependencies { ...@@ -62,8 +62,9 @@ dependencies {
implementation 'com.google.android.material:material:1.4.0' implementation 'com.google.android.material:material:1.4.0'
implementation 'com.google.protobuf:protobuf-java:3.13.0' implementation 'com.google.protobuf:protobuf-java:3.13.0'
implementation 'com.google.protobuf:protobuf-java-util:3.12.0' implementation 'com.google.protobuf:protobuf-java-util:3.12.0'
implementation 'com.tonystark.android:socket:latest.release' // implementation 'com.tonystark.android:socket:latest.release'
implementation 'com.tonystark.android:socket-server:latest.release' // implementation 'com.tonystark.android:socket-server:latest.release'
implementation 'com.guolindev.permissionx:permissionx:1.6.1' implementation 'com.guolindev.permissionx:permissionx:1.6.1'
implementation 'com.google.code.gson:gson:2.8.7' implementation 'com.google.code.gson:gson:2.8.7'
implementation 'io.netty:netty-all:4.1.4.Final'
} }
\ No newline at end of file
package com.ccwangluo.ccim; package com.ccwangluo.ccim;
import android.Manifest; import android.Manifest;
import android.content.Context;
import android.text.TextUtils;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
...@@ -34,7 +36,6 @@ import java.util.logging.Logger; ...@@ -34,7 +36,6 @@ import java.util.logging.Logger;
import ccim.protocol.Channel; import ccim.protocol.Channel;
import ccim.protocol.Chat; import ccim.protocol.Chat;
import ccim.protocol.Common;
import ccim.protocol.ContactOuterClass; import ccim.protocol.ContactOuterClass;
import ccim.protocol.Message; import ccim.protocol.Message;
import ccim.protocol.MessageSpec; import ccim.protocol.MessageSpec;
...@@ -74,9 +75,9 @@ public class CCIMClient { ...@@ -74,9 +75,9 @@ public class CCIMClient {
socketManageer.initServer(ip,port); socketManageer.initServer(ip,port);
} }
public void initSDK(String appKey, String userName, String extData, Long userId, Long ts, String sign, OnConnectListener resultCallback) { public void initSDK(Context context,String appKey, String userName, String extData, Long userId, Long ts, String sign, OnConnectListener resultCallback) {
socketManageer.initChat(appKey, userName, extData, userId, ts, sign, new OnConnectListener() { socketManageer.initChat(context,appKey, userName, extData, userId, ts, sign, new OnConnectListener() {
@Override @Override
public void onSocketConnection() { public void onSocketConnection() {
resultCallback.onSocketConnection(); resultCallback.onSocketConnection();
...@@ -515,19 +516,8 @@ public class CCIMClient { ...@@ -515,19 +516,8 @@ public class CCIMClient {
* 发送消息 * 发送消息
*/ */
public void sendTextMessage(String content, Long reciveUserId, ResultCallback callback) { public void sendTextMessage(String content, Long reciveUserId, ResultCallback callback) {
Contact contact = contacts.get(reciveUserId); if (TextUtils.isEmpty(content)){
if (contact == null){ callback.onFailed(900);
callback.onFailed(Common.StatusCode.STATUS_CODE_NOT_CONTACT_ERROR.getNumber());
return;
}
if (contact.getStatus().equals(Status.CONTACT_STATUS_BID_BLACKED) || contact.getStatus().equals(Status.CONTACT_STATUS_BLACK_LIST)){
callback.onFailed(Common.StatusCode.STATUS_CODE_CONTACT_BLOCKED_ME_ERROR.getNumber());
return;
}
if (contact.getStatus().equals(Status.CONTACT_STATUS_BLACKED)){
callback.onFailed(Common.StatusCode.STATUS_CODE_CONTACT_BLOCKED_ERROR.getNumber());
return;
} }
Message.SendMessageRequest messageRequest = Message.SendMessageRequest.newBuilder() Message.SendMessageRequest messageRequest = Message.SendMessageRequest.newBuilder()
.setContent(content) .setContent(content)
...@@ -714,7 +704,6 @@ public class CCIMClient { ...@@ -714,7 +704,6 @@ public class CCIMClient {
public void stopAndSendAudioMessage() { public void stopAndSendAudioMessage() {
MediaHelper.getInstance().release(); MediaHelper.getInstance().release();
String filePath = MediaHelper.getInstance().getFilePath(); String filePath = MediaHelper.getInstance().getFilePath();
} }
public void cancleAudioMessage() { public void cancleAudioMessage() {
......
package com.ccwangluo.ccim.listener; package com.ccwangluo.ccim.listener;
import com.xuhao.didi.core.pojo.OriginalData; import ccim.protocol.Chat;
public interface MessageListener { public interface MessageListener {
default void onServerConnect(){ default void onServerConnect(){
...@@ -10,5 +10,5 @@ public interface MessageListener { ...@@ -10,5 +10,5 @@ public interface MessageListener {
default void onServerDisConnect(){ default void onServerDisConnect(){
} }
void onMessageListener(OriginalData data); void onMessageListener(Chat.ChatResponseMessage data);
} }
package com.ccwangluo.ccim.manage; package com.ccwangluo.ccim.manage;
import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
...@@ -8,16 +9,9 @@ import com.ccwangluo.ccim.CCIMClient; ...@@ -8,16 +9,9 @@ import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.listener.MessageListener; import com.ccwangluo.ccim.listener.MessageListener;
import com.ccwangluo.ccim.listener.OnConnectListener; import com.ccwangluo.ccim.listener.OnConnectListener;
import com.ccwangluo.ccim.listener.ResultEventCallback; import com.ccwangluo.ccim.listener.ResultEventCallback;
import com.ccwangluo.ccim.modle.IrequestData; import com.ccwangluo.ccim.socket.NettyChatClient;
import com.ccwangluo.ccim.modle.MyIReaderProtocol; import com.ccwangluo.ccim.socket.SocketClient;
import com.ccwangluo.ccim.modle.PulseData;
import com.google.protobuf.util.JsonFormat; import com.google.protobuf.util.JsonFormat;
import com.xuhao.didi.core.pojo.OriginalData;
import com.xuhao.didi.socket.client.sdk.OkSocket;
import com.xuhao.didi.socket.client.sdk.client.ConnectionInfo;
import com.xuhao.didi.socket.client.sdk.client.OkSocketOptions;
import com.xuhao.didi.socket.client.sdk.client.action.SocketActionAdapter;
import com.xuhao.didi.socket.client.sdk.client.connection.IConnectionManager;
import java.util.logging.Logger; import java.util.logging.Logger;
...@@ -48,12 +42,7 @@ public class SocketManageer { ...@@ -48,12 +42,7 @@ public class SocketManageer {
private OnConnectListener onConnectListener; private OnConnectListener onConnectListener;
private ConnectionInfo chatInfo; private SocketClient socketClient;
public ConnectionInfo getChatInfo() {
return chatInfo;
}
public void connectChatServer(String appKey, String userName, String extData, Long userId, Long ts, String sign) { public void connectChatServer(String appKey, String userName, String extData, Long userId, Long ts, String sign) {
...@@ -83,12 +72,9 @@ public class SocketManageer { ...@@ -83,12 +72,9 @@ public class SocketManageer {
}); });
} }
public void initChat(String appKey, String userName, String extData, Long userId, Long ts, String sign, OnConnectListener resultCallback) { public void initChat(Context context,String appKey, String userName, String extData, Long userId, Long ts, String sign, OnConnectListener resultCallback) {
if (chatInfo != null && OkSocket.open(chatInfo).isConnect()) {
OkSocket.open(chatInfo).disconnect();
}
onConnectListener = resultCallback; onConnectListener = resultCallback;
this.chatInfo = initServer(SERVER_IP, SERVER_PORT, new MessageListener() { socketClient = new NettyChatClient(context,SERVER_IP, SERVER_PORT, new MessageListener() {
@Override @Override
public void onServerConnect() { public void onServerConnect() {
connectChatServer(appKey, userName, extData, userId, ts, sign); connectChatServer(appKey, userName, extData, userId, ts, sign);
...@@ -100,33 +86,32 @@ public class SocketManageer { ...@@ -100,33 +86,32 @@ public class SocketManageer {
} }
@Override @Override
public void onMessageListener(OriginalData data) { public void onMessageListener(Chat.ChatResponseMessage data) {
try { try {
Chat.ChatResponseMessage chatResponseMessage = Chat.ChatResponseMessage.parseFrom(data.getBodyBytes()); String json = JsonFormat.printer().print(data);
String json = JsonFormat.printer().print(chatResponseMessage);
logger.info(json); logger.info(json);
if (chatResponseMessage.hasHeartbeatRes()) { if (data.hasHeartbeatRes()) {
OkSocket.open(chatInfo).getPulseManager().feed(); // OkSocket.open(chatInfo).getPulseManager().feed();
return; return;
} }
if (chatResponseMessage.hasConnectionStateRes()) { if (data.hasConnectionStateRes()) {
connectState(); connectState();
return; return;
} }
if (chatResponseMessage.getHeader().getCode() == Common.StatusCode.STATUS_CODE_NO_AUTH_ERROR) { //断线重连 if (data.getHeader().getCode() == Common.StatusCode.STATUS_CODE_NO_AUTH_ERROR) { //断线重连
connectChatServer(appKey, userName, extData, userId, ts, sign); connectChatServer(appKey, userName, extData, userId, ts, sign);
} }
int seq = chatResponseMessage.getHeader().getSeq(); int seq = data.getHeader().getSeq();
ResultEventCallback<Chat.ChatResponseMessage> callBack = callBackManager.getCallBack(seq); ResultEventCallback<Chat.ChatResponseMessage> callBack = callBackManager.getCallBack(seq);
if (callBack != null) { if (callBack != null) {
handler.post(new Runnable() { handler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
if (chatResponseMessage.getHeader().getCode() == Common.StatusCode.STATUS_CODE_OK) { if (data.getHeader().getCode() == Common.StatusCode.STATUS_CODE_OK) {
callBack.onSuccess(chatResponseMessage); callBack.onSuccess(data);
} else { } else {
callBack.onFailed(chatResponseMessage.getHeader().getCode().getNumber()); callBack.onFailed(data.getHeader().getCode().getNumber());
} }
} }
}); });
...@@ -154,51 +139,9 @@ public class SocketManageer { ...@@ -154,51 +139,9 @@ public class SocketManageer {
* 心跳 * 心跳
*/ */
private void pulseData(Long frequency) { private void pulseData(Long frequency) {
OkSocketOptions.Builder okOptionsBuilder = new OkSocketOptions.Builder();
okOptionsBuilder.setPulseFrequency(frequency);
okOptionsBuilder.setReaderProtocol(new MyIReaderProtocol());
OkSocket.open(getChatInfo()).option(okOptionsBuilder.build());
Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder(); Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
builder.setHeartbeatReq(Chat.HeartbeatRequest.getDefaultInstance()); builder.setHeartbeatReq(Chat.HeartbeatRequest.getDefaultInstance());
OkSocket.open(getChatInfo()).getPulseManager() socketClient.heartBeat(frequency,builder.build());
.setPulseSendable(new PulseData(builder.build().toByteArray()))//只需要设置一次,下一次可以直接调用pulse()
.pulse();
}
private ConnectionInfo initServer(String ip, int port, MessageListener messageListener) {
ConnectionInfo authInfo = new ConnectionInfo(ip, port);
//调用OkSocket,开启这次连接的通道,拿到通道Manager
IConnectionManager manager = OkSocket.open(authInfo);
//获得当前连接通道的参配对象
OkSocketOptions.Builder okOptionsBuilder = new OkSocketOptions.Builder();
okOptionsBuilder.setReaderProtocol(new MyIReaderProtocol());
//将新的修改后的参配设置给连接管理器
manager.option(okOptionsBuilder.build());
//调用通道进行连接
manager.connect();
manager.registerReceiver(new SocketActionAdapter() {
@Override
public void onSocketConnectionSuccess(ConnectionInfo info, String action) {
super.onSocketConnectionSuccess(info, action);
messageListener.onServerConnect();
}
@Override
public void onSocketDisconnection(ConnectionInfo info, String action, Exception e) {
super.onSocketDisconnection(info, action, e);
if (onConnectListener != null) {
onConnectListener.onSocketDisconnection();
}
}
@Override
public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) {
super.onSocketReadResponse(info, action, data);
messageListener.onMessageListener(data);
}
});
return authInfo;
} }
public int sendRequest(Object request) { public int sendRequest(Object request) {
...@@ -250,12 +193,11 @@ public class SocketManageer { ...@@ -250,12 +193,11 @@ public class SocketManageer {
builder.setDeleteContactGroupReq((ContactOuterClass.DeleteContactGroupRequest) request); builder.setDeleteContactGroupReq((ContactOuterClass.DeleteContactGroupRequest) request);
} else if (request instanceof Chat.ConnectRequest) { } else if (request instanceof Chat.ConnectRequest) {
builder.setConnectReq((Chat.ConnectRequest) request); builder.setConnectReq((Chat.ConnectRequest) request);
} else if (request instanceof Chat.HeartbeatRequest) {
builder.setHeartbeatReq((Chat.HeartbeatRequest) request);
} }
socketClient.sendMsg(builder.build());
OkSocket.open(getChatInfo())
.send(new IrequestData(builder.build().toByteArray()));
return idPlus; return idPlus;
} }
...@@ -267,7 +209,7 @@ public class SocketManageer { ...@@ -267,7 +209,7 @@ public class SocketManageer {
} }
public void disConnect() { public void disConnect() {
OkSocket.open(chatInfo).disconnect(); socketClient.desTory();
} }
public void initServer(String ip, int port) { public void initServer(String ip, int port) {
......
package com.ccwangluo.ccim.modle;
import com.xuhao.didi.core.iocore.interfaces.ISendable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class IrequestData implements ISendable {
private final byte[] body;
public IrequestData(byte[] body){
this.body = body;
}
@Override
public byte[] parse() {
ByteBuffer bb = ByteBuffer.allocate(4 + body.length);
bb.order(ByteOrder.BIG_ENDIAN);
bb.putInt(body.length);
bb.put(body);
return bb.array();
}
}
package com.ccwangluo.ccim.modle;
import com.xuhao.didi.core.protocol.IReaderProtocol;
import java.nio.ByteOrder;
public class MyIReaderProtocol implements IReaderProtocol {
@Override
public int getHeaderLength() {
return 4;
}
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
@Override
public int getBodyLength(byte[] header, ByteOrder byteOrder) {
int value = toUnsignedInt(header[3]);
value |= toUnsignedInt((byte) (header[2] << 8));
value |= toUnsignedInt((byte) (header[1] << 16));
value |= toUnsignedInt((byte) (header[0] << 24));
return value;
}
}
package com.ccwangluo.ccim.modle;
import com.xuhao.didi.core.iocore.interfaces.IPulseSendable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class PulseData implements IPulseSendable {
private final byte[] body;
public PulseData(byte[] body){
this.body = body;
}
@Override
public byte[] parse() {
ByteBuffer bb = ByteBuffer.allocate(4 + body.length);
bb.order(ByteOrder.BIG_ENDIAN);
bb.putInt(body.length);
bb.put(body);
return bb.array();
}
}
package com.ccwangluo.ccim.socket;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.listener.MessageListener;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import ccim.protocol.Chat;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
public class NettyChatClient implements SocketClient {
private final Logger logger = Logger.getLogger(CCIMClient.class.getName());
private final MessageListener msglitener;
private ChannelFuture channelFuture;
private final String ip;
private final int port;
private Bootstrap bootstrap;
private Context context;
private ScheduledThreadPoolExecutor exec;
public NettyChatClient(Context context, String ip, int port, MessageListener msglistner) {
this.msglitener = msglistner;
this.ip = ip;
this.port = port;
this.context = context;
new Thread(new Runnable() {
@Override
public void run() {
initNetty(ip, port);
}
}).start();
}
private void initNetty(String ip, int port) {
//客户端需要一个事件循环组
EventLoopGroup group = new NioEventLoopGroup();
try {
//创建客户端启动对象
//注意:客户端使用的不是 ServerBootStrap 而是 Bootstrap
bootstrap = new Bootstrap();
//设置相关参数
bootstrap.group(group) //设置线程组
.channel(NioSocketChannel.class) //设置客户端通道的实现类(使用反射)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// Decoders
pipeline.addLast("frameDecoder",
new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4));
pipeline.addLast("protobufDecoder",
new ProtobufDecoder(Chat.ChatResponseMessage.getDefaultInstance()));
// Encoder
pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
pipeline.addLast("protobufEncoder", new ProtobufEncoder());
pipeline.addLast(new NettyClientHandler()); //加入自己的处理器
}
});
//启动客户端去连接服务器端
//关于 channelFuture 涉及到 netty 的异步模型
channelFuture = bootstrap.connect(ip, port).sync();
//给关闭通道进行监听
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
public boolean getConnectivityStatus(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (null != activeNetwork) {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return true;
if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return true;
}
return false;
}
@Override
public void sendMsg(Object msg) {
if (channelFuture == null) {
return;
}
new Thread(() -> {
if (channelFuture.channel().isActive()) {
channelFuture.channel().writeAndFlush(msg);
} else {
initNetty(ip, port);
}
}).start();
}
@Override
public void desTory() {
if (exec != null) {
exec.shutdownNow();
}
if (channelFuture != null) {
channelFuture.channel().close();
}
}
@Override
public void heartBeat(Long frequency, Object bytes) {
if (exec != null) {
exec.shutdownNow();
}
exec = new ScheduledThreadPoolExecutor(1);
//检查链接状态线程
exec.scheduleAtFixedRate(() -> {
if (getConnectivityStatus(context)) {
if (channelFuture != null && channelFuture.channel().isActive()) {
logger.info("check connect is active");
channelFuture.channel().writeAndFlush(bytes);
} else {
try {
logger.info("reconnect");
new Thread(() -> initNetty(ip, port)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, frequency, frequency, TimeUnit.MILLISECONDS);
}
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
/**
* 当通道就绪就会触发
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.info("channelActive");
msglitener.onServerConnect();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
logger.info("channelInactive");
msglitener.onServerDisConnect();
}
/**
* 当通道有读取事件时,会触发
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Chat.ChatResponseMessage data = (Chat.ChatResponseMessage) msg;
msglitener.onMessageListener(data);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
}
package com.ccwangluo.ccim.socket;
public interface SocketClient {
void sendMsg(Object bytes);
void desTory();
void heartBeat(Long frequency,Object bytes);
}
...@@ -48,7 +48,7 @@ public class MediaHelper { ...@@ -48,7 +48,7 @@ public class MediaHelper {
if (b) { if (b) {
fileDir.mkdirs(); fileDir.mkdirs();
} }
String fileName = System.currentTimeMillis() + ".amr"; // 文件名字 String fileName = System.currentTimeMillis() + ".aac"; // 文件名字
File file = new File(fileDir, fileName); // 文件路径 File file = new File(fileDir, fileName); // 文件路径
mMediaRecorder = new MediaRecorder(); mMediaRecorder = new MediaRecorder();
mFilePath = file.getAbsolutePath(); mFilePath = file.getAbsolutePath();
...@@ -61,8 +61,10 @@ public class MediaHelper { ...@@ -61,8 +61,10 @@ public class MediaHelper {
mMediaRecorder.setOutputFile(new File(file.getAbsolutePath())); mMediaRecorder.setOutputFile(new File(file.getAbsolutePath()));
} }
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置MediaRecorder的音频源为麦克风 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置MediaRecorder的音频源为麦克风
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); // 设置音频的格式 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置输出格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置音频的编码为AMR_NB mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 编码方式 // 设置音频的编码为AMR_NB
mMediaRecorder.setAudioSamplingRate(16000);
mMediaRecorder.setAudioChannels(1);
mMediaRecorder.prepare(); mMediaRecorder.prepare();
mMediaRecorder.start(); mMediaRecorder.start();
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
...@@ -76,7 +78,6 @@ public class MediaHelper { ...@@ -76,7 +78,6 @@ public class MediaHelper {
*/ */
public void release() { public void release() {
if (mMediaRecorder != null) { if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.release(); mMediaRecorder.release();
mMediaRecorder = null; mMediaRecorder = null;
} }
...@@ -105,14 +106,12 @@ public class MediaHelper { ...@@ -105,14 +106,12 @@ public class MediaHelper {
try { try {
mediaPlayer.setDataSource(filePath); mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare(); mediaPlayer.prepare();
//播放
mediaPlayer.start(); mediaPlayer.start();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
//获取生成的文件路径 //获取生成的文件路径
public String getFilePath() { public String getFilePath() {
return mFilePath; return mFilePath;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment