技术标签: android socket通讯 socket netty
service 类
private NetworkReceiver receiver;
public static final String TAG = NettyService.class.getName();
public NettyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
receiver = new NetworkReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//初始化Netty
NettyClient.getInstance().setListener(this);
connect();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
NettyClient.getInstance().setReconnectNum(0);
NettyClient.getInstance().disconnect();
}
private void connect() {
if (!NettyClient.getInstance().getConnectStatus()) {
new Thread(new Runnable() {
@Override
public void run() {
NettyClient.getInstance().connect();//连接服务器
}
}).start();
}
}
@Override
public void onMessageResponse(String messageHolder) {
notifyData(NettyActivity.MSG_FROM_SERVER, messageHolder);
}
private void notifyData(int type, String messageHolder) {
final Stack<NettyActivity> activities = ActivityManager.getInstance().getActivities();
for (NettyActivity activity : activities) {
if (activity == null || activity.isFinishing()) {
continue;
}
Message message = Message.obtain();
message.what = type;
message.obj = messageHolder;
activity.getHandler().sendMessage(message);
}
}
@Override
public void onServiceStatusConnectChanged(int statusCode) {
if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
Log.e(TAG, "connect sucessful");
sendAuthor();
} else {
Log.e(TAG, "connect fail statusCode = " + statusCode);
notifyData(NettyActivity.MSG_NET_WORK_ERROR, String.valueOf("服务器连接失败"));
}
}
/**
* 连接初始化 认证信息
* 发送认证信息 这个可以根据项目的实际需要数据类型 进行修改
*/
private void sendAuthor() {
final Netty_RegisterInfo nettyRegisterInfo = new Netty_RegisterInfo();
nettyRegisterInfo.setUserId(1);
nettyRegisterInfo.setUserType(2);
final NettyBaseFeed<Netty_RegisterInfo> reqRegisterVONettyBaseFeed = new NettyBaseFeed<>();
reqRegisterVONettyBaseFeed.setCmd(1);
reqRegisterVONettyBaseFeed.setModule(1);
reqRegisterVONettyBaseFeed.setData(nettyRegisterInfo);
NettyClient.getInstance().sendMessage(reqRegisterVONettyBaseFeed, null);
}
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { // connected to the internet
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI
|| activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
connect();
Log.e(TAG, "connecting ...");
}
}
}
}
NettyClient类
public class NettyClient {
private static NettyClient nettyClient = new NettyClient();
private EventLoopGroup group;
private NettyListener listener;
private Channel channel;
private boolean isConnect = false;
private int reconnectNum = Integer.MAX_VALUE;
private long reconnectIntervalTime = 5000;
public final static String TAG = NettyClient.class.getName();
private final Gson gson;
private Bootstrap bootstrap;
public NettyClient() {
gson = new Gson();
}
public static NettyClient getInstance() {
return nettyClient;
}
public synchronized NettyClient connect() {
if (!isConnect) {
group = new NioEventLoopGroup();
bootstrap = new Bootstrap().group(group)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.SO_BACKLOG, 128)
.option(ChannelOption.TCP_NODELAY, true)
.channel(NioSocketChannel.class)
.handler(new NettyClientInitializer(listener));
try {
ChannelFuture future = bootstrap.connect(UrlConstant.SOCKET_HOST, UrlConstant.SOCKET_PORT).sync();
if (future != null && future.isSuccess()) {
channel = future.channel();
isConnect = true;
} else {
isConnect = false;
}
} catch (Exception e) {
e.printStackTrace();
listener.onServiceStatusConnectChanged(NettyListener.STATUS_CONNECT_ERROR);
reconnect();
}
}
return this;
}
public void disconnect() {
group.shutdownGracefully();
}
public void reconnect() {
if (reconnectNum > 0 && !isConnect) {
reconnectNum--;
try {
Thread.sleep(reconnectIntervalTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
disconnect();
connect();
} else {
disconnect();
}
}
public Channel getChannel() {
return channel;
}
/**
* 发送消息
*
* @param vo 发送消息的Json对象
* @param futureListener 发送成功与否的监听
*/
public void sendMessage(NettyBaseFeed vo, FutureListener futureListener) {
boolean flag = channel != null && isConnect;
if (!flag) {
Log.e(TAG, "------尚未连接");
return;
}
final String s = gson.toJson(vo);
if (futureListener == null) {
channel.writeAndFlush(s).addListener(new FutureListener() {
@Override
public void success() {
Log.e(TAG, "发送成功--->" + s);
}
@Override
public void error() {
Log.e(TAG, "发送失败--->" + s);
}
});
} else {
channel.writeAndFlush(s).addListener(futureListener);
}
}
/**
* 设置重连次数
*
* @param reconnectNum 重连次数
*/
public void setReconnectNum(int reconnectNum) {
this.reconnectNum = reconnectNum;
}
/**
* 设置重连时间间隔
*
* @param reconnectIntervalTime 时间间隔
*/
public void setReconnectIntervalTime(long reconnectIntervalTime) {
this.reconnectIntervalTime = reconnectIntervalTime;
}
public boolean getConnectStatus() {
return isConnect;
}
/**
* 设置连接状态
*
* @param status
*/
public void setConnectStatus(boolean status) {
this.isConnect = status;
}
public void setListener(NettyListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener == null ");
}
this.listener = listener;
}
}
接收服务器的消息 从NettyClientHandler的回调方法channelRead0 这里开始 调用至service之后再遍历NettyActivity的子类 通过主线程的Handler 分发至主线程
public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
private static final String TAG = NettyClientHandler.class.getName();
private NettyListener listener;
public NettyClientHandler(NettyListener listener) {
this.listener = listener;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
NettyClient.getInstance().setConnectStatus(true);
listener.onServiceStatusConnectChanged(NettyListener.STATUS_CONNECT_SUCCESS);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
NettyClient.getInstance().setConnectStatus(false);
listener.onServiceStatusConnectChanged(NettyListener.STATUS_CONNECT_CLOSED);
NettyClient.getInstance().reconnect();
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String byteBuf) throws Exception {
Log.e(TAG, "thread == " + Thread.currentThread().getName());
Log.e(TAG, "来自服务器的消息 ====》" + byteBuf);
listener.onMessageResponse(byteBuf);
}
主线程发送消息
NettyClient.getInstance().sendMessage(baseFeed, null);
文章浏览阅读155次。从keil4过渡到MDK5后,遇到的第一个问题就是下载时MDK提示需要将keil的固件升级,一想环境不一样,估计估计需要升级一下,于是手残点了升级,于是就悲剧了,项目中断,倒腾固件修复倒腾了一天,下面说下遇到的问题。固件修复后,jlink上灯就不亮了,不亮就不亮,固件升级原来也做过,不难,可是好像忘了一个问题,原来的开发环境在winxp下,后来换成了win7 64位,就是这个环境让我..._win7 sp1补丁包和jlink
文章浏览阅读185次。Task 4 基于深度学习的文本分类1与传统机器学习不同,深度学习即提供特征提取功能,也可以完成分类的功能。4.1 学习目标1.学习FastText的使用和基础原理2.学会使用验证集进行调参4.2 现有文本表示方法的缺陷上一章节介绍了几种文本表示方法:1.One-hot2.Bag of Words3.N-gram4.TF-IDF上述方法或多或少都存在一定的问题:转换得到的向量维度很高,需要较长的训练时间;没有考虑单词与单词之间的关系,只是进行了统计。与上述方法不同,深度学习也可以用于_基于tf的文本分类
文章浏览阅读160次。sessionsession是什么session是因为cookie的弊端(存放在客户端,容易被客户修改伪造,数据量大也有纯传输问题) 才被做出来的,用session存储在服务器中,这让他的安全性也相对高一点session是一次浏览器和服务器的交互的会话,session也是一种存储方案服务器建立一个session,会在客户端建立一个唯一的识别(目的是为了只有这个客户端才能获得这个sessionsession的标识也会根据浏览器有关系 不同的浏览器的同一用户是不同的标识session 的运作通过_session rolling
文章浏览阅读1.4k次。一、前言在Duilib的简单使用(一、duilib demo)中我们介绍了利用duilib简单的构造一个项目在Duilib的简单使用(二、xml实现界面与业务分离)中我们介绍了XML在duilib中的使用在Duilib的简单使用(三、界面逻辑交互)中我们已经知道如何简单的进行界面的交互这一篇,我们来提一下,Duilib强大的一键换肤功能。二、函数介绍Duilib是一个以贴图为主要表现手段的界面库,实现换肤非常简单,可以通过给控件设置不同的图片来实现换肤,比如给需要换肤的控件调用CControlU_dulib皮肤
文章浏览阅读2.1w次,点赞37次,收藏340次。SpringMVC常见面试题总结1. 什么是SpringMVC?SpringMVC是一种基于 Java 的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring框架的一个模块。它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。2.什么是MVC模式?MVC的全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范。它是_springmvc面试
文章浏览阅读1.2w次,点赞7次,收藏16次。思路利用plt.clf()在每次画完图片后,更新画布。代码#导入两个包import matplotlib.pyplot as pltimport numpy as np #数据准备x = np.arange(27)x = np.reshape(x, (3,9)) #建立for循环语句,绘制x的前三列for i in range(3): plt.plot(x[:,i]) # plt.show() #保存图片的时候不要plt.show() plt.savefig
文章浏览阅读1.6w次,点赞6次,收藏8次。开发接口时,出现个离奇问题。在对接第三方接口时,按对方接口参数进行传参,却一直接收不到,为null值,检查所有代码,并不是代码问题。我将代码整理并创建简单接口进行测试,如图:测试实体类测试实现类postman测试参数debug接收参数为null在测试时,无论如何参数都为接收都为null,在折腾许久,终于发现时实体类里的@Data注解的原因一下是我截取出的get/set方法;最终原因就是出在参数名命名不规范,造成@Data注解在生产class文件时出现问题。造成所生成的get/set方_前端传参,java接收为null
文章浏览阅读592次。原标题:MIUI官方回应:米6公交开卡系服务升级、NFC功能可正常使用近日,有消息称小米6因为系统升级暂时关闭了NFC公交开卡服务,或涉及虚假宣传。对此,小米官方也给予了回应,以下为小米MIUI官方在论坛上的回应:NFC(近场通信)功能拥有三种工作模式:读卡器模式(Reader/Writer mode)、点对点模式(P2P mode)、卡模拟模式(Card emulation mode)。读卡器模..._小米6读卡器
文章浏览阅读3.1w次,点赞4次,收藏3次。先贴出报错:字面意思是:babel警告,代码生成器已经将这块js去除了styling, 因为他超过了500KB.解决方案:{ test: /.js$/, exclude: /node_modules/, use: 'babel-loader'},..._the code generator has deoptimised the styling of undefined as it exceeds th
文章浏览阅读1.3w次,点赞3次,收藏32次。今天做蠕虫弄个memz病毒,把虚拟机搞崩了,重装了一下才解决,详细的了解了一下这种病毒。MEMZ病毒:MEMZ病毒又称彩虹猫病毒,在运行时,该病毒会不断弹窗导致系统无法正常运行,如果尝试结束MEMZ进程或重启系统,桌面会弹出无数个包含“火星文”的消息对话框,随后计算机进入蓝屏状态。重启后,会在屏幕顶部出现一段英文(译文:你的电脑已经被MEMZ病毒损坏,现在一起来欣赏彩虹猫吧),最后出现一个跳跃的“彩虹猫”动画。运行环境:虚拟机!!!!源代码:Github上有源码,不过好像是越南语的注释,不太_memz
文章浏览阅读551次。本次主要介绍,无论使用的xpath表达式中是否包含text()方法,最后都可以获取目标标签下的文本。使用的依然是etree.HTML和etree.tostring方法。1.思路首先将字符串源码转换成_Element对象,然后使用_Element对象的xpath()方法解析xpath表达式。如果通过xpath表达式解析得到的是文本对象,那么先将文本对象(也是字符串)转换成_Element对象,最后通过etree.tostring方法获取_Element对象中的文本内容(可以参考这里)。2.代码实现_datas =etree.html(data)
文章浏览阅读728次,点赞13次,收藏19次。大语言模型乐园,国内外大模型集合,持续更新...