Commit 58077cdf authored by sheteng's avatar sheteng

socket框架切换成netty

parent ad44c82d
......@@ -61,6 +61,6 @@ dependencies {
implementation 'com.google.protobuf:protobuf-java:3.13.0'
implementation 'com.google.protobuf:protobuf-java-util:3.12.0'
implementation 'com.guolindev.permissionx:permissionx:1.6.1'
implementation 'com.tonystark.android:socket:latest.release'
implementation 'com.tonystark.android:socket-server:latest.release'
implementation 'io.netty:netty-all:4.1.4.Final'
}
\ No newline at end of file
package com.ccwangluo.im.data;
import android.content.Context;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
......@@ -26,7 +28,7 @@ public class LoginViewModel extends ViewModel {
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);
String extData = "extData";
Long ts = System.currentTimeMillis();
......@@ -35,7 +37,7 @@ public class LoginViewModel extends ViewModel {
//sign计算在服务器,本地不要暴露appsecrect
String sign = HmacUtil.stringToSign(appsecret, data);
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
public void onSocketConnection() {
loginState.postValue(true);
......
......@@ -2,6 +2,7 @@ package com.ccwangluo.im.ui.dashboard;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
......@@ -14,6 +15,7 @@ import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.ccim.util.MediaHelper;
import com.ccwangluo.im.adapter.PrivateMsgAdapter;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentConnectBinding;
......@@ -26,7 +28,7 @@ public class ConnectFragment extends Fragment {
private LoginViewModel loginViewModel;
private PrivateMsgAdapter privaetMsgAdapter;
private List<PushPrivateMsgRes.MessageDTO> list = new ArrayList<>();
private String filePath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -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();
}
}
\ No newline at end of file
......@@ -54,8 +54,8 @@ public class ContactsFragment extends Fragment {
@Override
public void onClick(Contact contact) {
Bundle bundle = new Bundle();
bundle.putSerializable("contact",contact);
navController.navigate(R.id.navigation_connect,bundle);
bundle.putSerializable("contact", contact);
navController.navigate(R.id.navigation_connect, bundle);
}
});
......@@ -66,7 +66,7 @@ public class ContactsFragment extends Fragment {
public void onChanged(Collection<Contact> contacts) {
contactList.clear();
contactList.addAll(contacts);
contactExpandableAdapter.reFreshData(contactGroupList,contactList);
contactExpandableAdapter.reFreshData(contactGroupList, contactList);
}
});
......@@ -75,7 +75,7 @@ public class ContactsFragment extends Fragment {
public void onChanged(Collection<ContactGroup> contactGroups) {
contactGroupList.clear();
contactGroupList.addAll(contactGroups);
contactExpandableAdapter.reFreshData(contactGroupList,contactList);
contactExpandableAdapter.reFreshData(contactGroupList, contactList);
}
});
......@@ -94,7 +94,7 @@ public class ContactsFragment extends Fragment {
CCIMClient.getInstance().searchUser(userName, new ResultEventCallback<List<User>>() {
@Override
public void onSuccess(List<User> users) {
if (users.size() > 0) {
if (users != null && users.size() > 0) {
showSearchResultdialog(users);
}
}
......@@ -126,7 +126,7 @@ public class ContactsFragment extends Fragment {
CCIMClient.getInstance().createContactGroup(groupname, new ResultEventCallback<Long>() {
@Override
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();
}
});
......
......@@ -66,7 +66,7 @@ public class LoginActivity extends AppCompatActivity {
String appSecret = binding.appSecret.getText().toString();
String ip = binding.ip.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 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity2">
<ListView
android:id="@+id/msg_list"
android:layout_width="match_parent"
......@@ -17,21 +18,44 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<EditText
android:id="@+id/send_edit"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
android:text="发送文字" />
</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>
\ No newline at end of file
......@@ -62,8 +62,9 @@ dependencies {
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.google.protobuf:protobuf-java:3.13.0'
implementation 'com.google.protobuf:protobuf-java-util:3.12.0'
implementation 'com.tonystark.android:socket:latest.release'
implementation 'com.tonystark.android:socket-server:latest.release'
// implementation 'com.tonystark.android:socket:latest.release'
// implementation 'com.tonystark.android:socket-server:latest.release'
implementation 'com.guolindev.permissionx:permissionx:1.6.1'
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;
import android.Manifest;
import android.content.Context;
import android.text.TextUtils;
import androidx.fragment.app.FragmentActivity;
......@@ -34,7 +36,6 @@ import java.util.logging.Logger;
import ccim.protocol.Channel;
import ccim.protocol.Chat;
import ccim.protocol.Common;
import ccim.protocol.ContactOuterClass;
import ccim.protocol.Message;
import ccim.protocol.MessageSpec;
......@@ -74,9 +75,9 @@ public class CCIMClient {
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
public void onSocketConnection() {
resultCallback.onSocketConnection();
......@@ -515,19 +516,8 @@ public class CCIMClient {
* 发送消息
*/
public void sendTextMessage(String content, Long reciveUserId, ResultCallback callback) {
Contact contact = contacts.get(reciveUserId);
if (contact == null){
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;
if (TextUtils.isEmpty(content)){
callback.onFailed(900);
}
Message.SendMessageRequest messageRequest = Message.SendMessageRequest.newBuilder()
.setContent(content)
......@@ -714,7 +704,6 @@ public class CCIMClient {
public void stopAndSendAudioMessage() {
MediaHelper.getInstance().release();
String filePath = MediaHelper.getInstance().getFilePath();
}
public void cancleAudioMessage() {
......
package com.ccwangluo.ccim.listener;
import com.xuhao.didi.core.pojo.OriginalData;
import ccim.protocol.Chat;
public interface MessageListener {
default void onServerConnect(){
......@@ -10,5 +10,5 @@ public interface MessageListener {
default void onServerDisConnect(){
}
void onMessageListener(OriginalData data);
void onMessageListener(Chat.ChatResponseMessage data);
}
package com.ccwangluo.ccim.manage;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
......@@ -8,16 +9,9 @@ import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.listener.MessageListener;
import com.ccwangluo.ccim.listener.OnConnectListener;
import com.ccwangluo.ccim.listener.ResultEventCallback;
import com.ccwangluo.ccim.modle.IrequestData;
import com.ccwangluo.ccim.modle.MyIReaderProtocol;
import com.ccwangluo.ccim.modle.PulseData;
import com.ccwangluo.ccim.socket.NettyChatClient;
import com.ccwangluo.ccim.socket.SocketClient;
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;
......@@ -48,12 +42,7 @@ public class SocketManageer {
private OnConnectListener onConnectListener;
private ConnectionInfo chatInfo;
public ConnectionInfo getChatInfo() {
return chatInfo;
}
private SocketClient socketClient;
public void connectChatServer(String appKey, String userName, String extData, Long userId, Long ts, String sign) {
......@@ -83,12 +72,9 @@ public class SocketManageer {
});
}
public void initChat(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();
}
public void initChat(Context context,String appKey, String userName, String extData, Long userId, Long ts, String sign, OnConnectListener resultCallback) {
onConnectListener = resultCallback;
this.chatInfo = initServer(SERVER_IP, SERVER_PORT, new MessageListener() {
socketClient = new NettyChatClient(context,SERVER_IP, SERVER_PORT, new MessageListener() {
@Override
public void onServerConnect() {
connectChatServer(appKey, userName, extData, userId, ts, sign);
......@@ -100,33 +86,32 @@ public class SocketManageer {
}
@Override
public void onMessageListener(OriginalData data) {
public void onMessageListener(Chat.ChatResponseMessage data) {
try {
Chat.ChatResponseMessage chatResponseMessage = Chat.ChatResponseMessage.parseFrom(data.getBodyBytes());
String json = JsonFormat.printer().print(chatResponseMessage);
String json = JsonFormat.printer().print(data);
logger.info(json);
if (chatResponseMessage.hasHeartbeatRes()) {
OkSocket.open(chatInfo).getPulseManager().feed();
if (data.hasHeartbeatRes()) {
// OkSocket.open(chatInfo).getPulseManager().feed();
return;
}
if (chatResponseMessage.hasConnectionStateRes()) {
if (data.hasConnectionStateRes()) {
connectState();
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);
}
int seq = chatResponseMessage.getHeader().getSeq();
int seq = data.getHeader().getSeq();
ResultEventCallback<Chat.ChatResponseMessage> callBack = callBackManager.getCallBack(seq);
if (callBack != null) {
handler.post(new Runnable() {
@Override
public void run() {
if (chatResponseMessage.getHeader().getCode() == Common.StatusCode.STATUS_CODE_OK) {
callBack.onSuccess(chatResponseMessage);
if (data.getHeader().getCode() == Common.StatusCode.STATUS_CODE_OK) {
callBack.onSuccess(data);
} else {
callBack.onFailed(chatResponseMessage.getHeader().getCode().getNumber());
callBack.onFailed(data.getHeader().getCode().getNumber());
}
}
});
......@@ -154,51 +139,9 @@ public class SocketManageer {
* 心跳
*/
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();
builder.setHeartbeatReq(Chat.HeartbeatRequest.getDefaultInstance());
OkSocket.open(getChatInfo()).getPulseManager()
.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;
socketClient.heartBeat(frequency,builder.build());
}
public int sendRequest(Object request) {
......@@ -250,12 +193,11 @@ public class SocketManageer {
builder.setDeleteContactGroupReq((ContactOuterClass.DeleteContactGroupRequest) request);
} else if (request instanceof Chat.ConnectRequest) {
builder.setConnectReq((Chat.ConnectRequest) request);
} else if (request instanceof Chat.HeartbeatRequest) {
builder.setHeartbeatReq((Chat.HeartbeatRequest) request);
}
OkSocket.open(getChatInfo())
.send(new IrequestData(builder.build().toByteArray()));
socketClient.sendMsg(builder.build());
return idPlus;
}
......@@ -267,7 +209,7 @@ public class SocketManageer {
}
public void disConnect() {
OkSocket.open(chatInfo).disconnect();
socketClient.desTory();
}
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 {
if (b) {
fileDir.mkdirs();
}
String fileName = System.currentTimeMillis() + ".amr"; // 文件名字
String fileName = System.currentTimeMillis() + ".aac"; // 文件名字
File file = new File(fileDir, fileName); // 文件路径
mMediaRecorder = new MediaRecorder();
mFilePath = file.getAbsolutePath();
......@@ -61,8 +61,10 @@ public class MediaHelper {
mMediaRecorder.setOutputFile(new File(file.getAbsolutePath()));
}
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置MediaRecorder的音频源为麦克风
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); // 设置音频的格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置音频的编码为AMR_NB
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置输出格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 编码方式 // 设置音频的编码为AMR_NB
mMediaRecorder.setAudioSamplingRate(16000);
mMediaRecorder.setAudioChannels(1);
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (IllegalStateException e) {
......@@ -76,7 +78,6 @@ public class MediaHelper {
*/
public void release() {
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
}
......@@ -105,14 +106,12 @@ public class MediaHelper {
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
//播放
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取生成的文件路径
public String getFilePath() {
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