安卓websocket(客服端和服务端写在app端) 案例
废话不多说直接上代码
首选导入
implementation "org.java-websocket:Java-WebSocket:1.4.0"
package com.zx.qnncpds.androidwbsocket;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;import androidx.appcompat.app.AppCompatActivity;import com.zx.qnncpds.androidwbsocket.client.ClientActivity;
import com.zx.qnncpds.androidwbsocket.service.ServiceActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn1;private Button btn2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn1 = findViewById(R.id.btn1);btn2 = findViewById(R.id.btn2);btn1.setOnClickListener(this);btn2.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn1://客户端startActivity(new Intent(MainActivity.this, ClientActivity.class));break;case R.id.btn2://服务端startActivity(new Intent(MainActivity.this, ServiceActivity.class));break;default:break;}}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="客服端" /><Buttonandroid:id="@+id/btn2"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="服务端" />
</LinearLayout>
客服端
package com.zx.qnncpds.androidwbsocket.client;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;import com.zx.qnncpds.androidwbsocket.R;import java.net.URI;
import java.net.URISyntaxException;public class ClientActivity extends AppCompatActivity implements ClientWebSocketListener {private WebSocketClient webSocketClient;private Button btn_send;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_client);btn_send=findViewById(R.id.btn_send);btn_send.setOnClickListener(v -> sendMessage("测试消息"));try {// 替换为你的WebSocket服务器URIURI uri = new URI("ws://10.10.10.104:9007");webSocketClient = new WebSocketClient(uri, this);webSocketClient.connect();} catch (URISyntaxException e) {e.printStackTrace();}}/*** @param message 当WebSocket接收到消息时调用此方法*/@Overridepublic void onMessage(final String message) {}/*** @param message 连接打开*/@Overridepublic void onOpen(String message) {}/*** @param message 连接关闭*/@Overridepublic void onClose(String message) {}/*** @param message 出现错误*/@Overridepublic void onError(String message) {}public void sendMessage(String message) {// 发送一个消息到WebSocket服务器if (webSocketClient != null && webSocketClient.isOpen()) {webSocketClient.send(message);}}@Overrideprotected void onDestroy() {super.onDestroy();// 关闭WebSocket连接以避免内存泄露if (webSocketClient != null) {webSocketClient.close();}}
}
package com.zx.qnncpds.androidwbsocket.client;public interface ClientWebSocketListener {/*** @param message 当WebSocket接收到消息时调用此方法*/void onMessage(final String message);/*** @param message 连接打开*/void onOpen(final String message);/*** @param message 连接关闭*/void onClose(final String message);/*** @param message 出现错误*/void onError(final String message);
}
package com.zx.qnncpds.androidwbsocket.client;import org.java_websocket.handshake.ServerHandshake;import java.net.URI;public class WebSocketClient extends org.java_websocket.client.WebSocketClient {private ClientWebSocketListener webSocketListener;public WebSocketClient(URI serverUri, ClientWebSocketListener listener) {super(serverUri);this.webSocketListener = listener;}@Overridepublic void onOpen(ServerHandshake handshakeData) {System.out.println("WebSocket 连接打开");if (webSocketListener != null) {webSocketListener.onOpen("WebSocket 连接打开");}}@Overridepublic void onMessage(String message) {if (webSocketListener != null) {webSocketListener.onMessage(message);}}@Overridepublic void onClose(int code, String reason, boolean remote) {System.out.println("WebSocket 连接关闭");if (webSocketListener != null) {webSocketListener.onClose("WebSocket 连接关闭");}}@Overridepublic void onError(Exception ex) {System.out.println("WebSocket 出现错误: " + ex.getMessage());if (webSocketListener != null) {webSocketListener.onError("WebSocket 出现错误: " + ex.getMessage());}}
}
服务端
package com.zx.qnncpds.androidwbsocket.service;import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;import com.zx.qnncpds.androidwbsocket.R;import org.java_websocket.WebSocket;import java.io.IOException;public class ServiceActivity extends Activity implements ServiceWebSocketListener {// WebSocket服务器的实例private AndroidWebSocketServer server;private TextView tv_state;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_service);tv_state=findViewById(R.id.tv_state);// 创建并启动WebSocket服务器server = new AndroidWebSocketServer(8887, this);server.start();}@Overridepublic void onClientOpen(WebSocket conn, String address) {runOnUiThread(() -> {// 更新UI显示连接的客户端的地址// 例如:更新一个文本视图来显示已连接tv_state.setText(address);});}@Overridepublic void onClientClose(WebSocket conn, int code, String reason, boolean remote) {runOnUiThread(() -> {// 更新UI以表示客户端断开连接// 例如:更新列表视图中的项目tv_state.setText("客户端以断开");});}@Overridepublic void onClientMessage(WebSocket conn, String message) {runOnUiThread(() -> {// 在UI上展示收到的消息// 例如:将消息添加到聊天窗口tv_state.setText(message);});}@Overridepublic void onClientError(WebSocket conn, Exception ex) {runOnUiThread(() -> {// 在UI上展示错误信息// 例如:展示一个错误弹窗});}@Overridepublic void onServerStart() {runOnUiThread(() -> {// 更新UI表示服务器已经启动// 例如:改变一个文本视图的文本tv_state.setText("服务器已启动");});}@Overrideprotected void onDestroy() {super.onDestroy();if (server != null) {try {server.stop();} catch (IOException | InterruptedException e) {throw new RuntimeException(e);}}}// 广播消息给所有WebSocket客户端public void broadcastToAll(String message) {server.broadcastMessage(message);}// 发送消息给特定的WebSocket客户端public void sendToClient(WebSocket client, String message) {server.sendMessageToClient(client, message);}
}
package com.zx.qnncpds.androidwbsocket.service;import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;import java.net.InetSocketAddress;public class AndroidWebSocketServer extends WebSocketServer {// 事件监听器,用于将事件通知给ServiceActivityprivate ServiceWebSocketListener serviceWebSocketListener;/*** 构造函数。* @param port 服务器侦听的端口号。* @param serviceWebSocketListener 事件发生时的回调监听器。*/public AndroidWebSocketServer(int port, ServiceWebSocketListener serviceWebSocketListener) {super(new InetSocketAddress(port));this.serviceWebSocketListener = serviceWebSocketListener;}public AndroidWebSocketServer(int port) {super(new InetSocketAddress(port));}@Overridepublic void onOpen(WebSocket conn, ClientHandshake handshake) {// 客户端连接打开时调用监听器的onClientOpen方法String address = conn.getRemoteSocketAddress().getAddress().getHostAddress();serviceWebSocketListener.onClientOpen(conn, address);}@Overridepublic void onClose(WebSocket conn, int code, String reason, boolean remote) {// 客户端连接关闭时调用监听器的onClientClose方法String address = conn.getRemoteSocketAddress().getAddress().getHostAddress();serviceWebSocketListener.onClientClose(conn, code, reason, remote);}@Overridepublic void onMessage(WebSocket conn, String message) {// 接收到客户端消息时调用监听器的onClientMessage方法serviceWebSocketListener.onClientMessage(conn, message);}@Overridepublic void onError(WebSocket conn, Exception ex) {// 连接发生错误时调用监听器的onClientError方法serviceWebSocketListener.onClientError(conn, ex);}@Overridepublic void onStart() {// WebSocket服务器启动时调用监听器的onServerStart方法serviceWebSocketListener.onServerStart();}// 发送消息到所有连接的WebSocket客户端public void broadcastMessage(String message) {broadcast(message);}// 发送消息到特定的WebSocket客户端public void sendMessageToClient(WebSocket conn, String message) {if (conn != null) {conn.send(message);}}
}
package com.zx.qnncpds.androidwbsocket.service;import org.java_websocket.WebSocket;public interface ServiceWebSocketListener {/**当客户端连接打开时调用* @param conn* @param address*/void onClientOpen(WebSocket conn, String address);// 当客户端连接关闭时调用/** 当客户端连接关闭时调用* @param conn* @param code* @param reason* @param remote*/void onClientClose(WebSocket conn, int code, String reason, boolean remote);/**当接收到客户端消息时调用* @param conn* @param message*/void onClientMessage(WebSocket conn, String message);/*** 当客户端连接发生错误时调用* @param conn* @param ex*/void onClientError(WebSocket conn, Exception ex);/***当WebSocket服务器启动时调用*/void onServerStart();
}
布局加一个文本这就不写了(服务端和客服端都一样)
项目案例 https://download.csdn.net/download/qq_41733851/88885469?spm=1001.2014.3001.5503
相关文章:
安卓websocket(客服端和服务端写在app端) 案例
废话不多说直接上代码 首选导入 implementation "org.java-websocket:Java-WebSocket:1.4.0" package com.zx.qnncpds.androidwbsocket;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button;import a…...
C++面试宝典第34题:整数反序
题目 给出一个不多于5位的整数, 进行反序处理。要求: 1、求出它是几位数。 2、分别输出每一位数字。仅数字间以空格间隔, 负号与数字之间不需要间隔。如果是负数,负号加在第一个数字之前, 与数字没有空格间隔。注意:最后一个数字后没有空格。 3、按逆序输出各位数字。逆序后…...
微信商城小程序设计
简介 完整实现了集下单、支付、物流、评价、退款等功能的微信商城版小程序以及商城的管理后台,涉及商品的分类、规格的配置,商品上架等等。 产品效果图 项目链接 java后台:mall微信商城: 微信商城小程序。完整实现了集下单、支付、物流、评…...
如何合理布局子图--确定MATLAB的subplot子图位置参数
确定MATLAB的subplot子图位置参数 目录 确定MATLAB的subplot子图位置参数摘要1. 问题描述2. 计算过程2.1 确定子图的大小和间距2.2 计算合适的figure大小2.3 计算每个子图的position数据 3. MATLAB代码实现3.1 MATLAB代码3.2 绘图结果 4. 总结 摘要 在MATLAB中,使用…...
【MySQL】基于Docker搭建MySQL一主二从集群
本文记录了搭建mysql一主二从集群,这样的一个集群master为可读写,slave为只读。过程中使用了docker,便于快速搭建单体mysql。 1,准备docker docker的安装可以参考之前基于yum安装docker的文章[1]。 容器相关命令[2]。 查看正在…...
k8s 集群调度,标签,亲和性和反亲和性,污点和容忍,pod启动状态 排错详解
目录 pod启动创建过程 kubelet持续监听的原因 调度概念 调度约束 调度过程 优点 原理 优先级选项 示例 指定调度节点 标签基本操作 获取标签帮助 添加标签(Add Labels): 更新标签(Update Labels) 删除标…...
Idea 启动报错 failed to create jvm:jvm path url
1、情况 针对于在 idea 中,通过界面的形式改了 -Xmx 等类似的参数,并且设置的值过大,导致下次启动 idea 报错 2、解决 找到如图所示的文件 打开编辑该文件,把类似 -Xmx 等参数的值调小,保存文件并关闭࿰…...
20款Visual Studio实用插件推荐
前言 俗话说的好工欲善其事必先利其器,安装一些实用的Visual Studio插件对自己日常的开发和工作效率能够大大的提升,避免996从选一款好的IDE实用插件开始。以下是我认为比较实用的Visual Studio插件,希望对大家有所帮助。 各位小伙伴有更好的…...
基于SpringBoot的在线拍卖系统
目录 1、 前言介绍 2、主要技术 3、系统流程和逻辑 4、系统结构设计 5、数据库设计表 6、运行截图(部分) 6.1管理员功能模块 6.2用户功能模块 6.3前台首页功能模块 7、源码获取 基于SpringBoot的在线拍卖系统录像 1、 前言介绍 随着社会的发展,社会的各行…...
“互动+消费”时代,借助华为云GaussDB重构新零售中消费逻辑
场与人的关系 “人—货—场”是零售中重要的三要素,我们一直在追求,将零售中的人、货、场进行数字化并在云端进行整合,形成属于我们自己的云平台。 随着互联网技术为信息提供的便利,消费者的集体力量正在逐渐形成一股强大的反向…...
AI大全-通往AGI之路
背景 自从AI大模型出来之后,就有很多做资源整理的社区,整理学习资料,整理各种AI工具大全,我也整理过一段时间的最新AI的资讯,也曾尝试去弄一个AI的入口类的东西。但是最近看到一个在飞书上的分享,我觉得他…...
CSS中如何解决 1px 问题?
1px 问题指的是:在一些 Retina屏幕 的机型上,移动端页面的 1px 会变得很粗,呈现出不止 1px 的效果。原因很简单——CSS 中的 1px 并不能和移动设备上的 1px 划等号。它们之间的比例关系有一个专门的属性来描述: window.devicePix…...
IO 与 NIO
优质博文:IT-BLOG-CN 一、阻塞IO / 非阻塞NIO 阻塞IO:当一条线程执行read()或者write()方法时,这条线程会一直阻塞直到读取到了一些数据或者要写出去的数据已经全部写出,在这期间这条线程不能做任何其他的事情。 非阻塞NIO&…...
YOLOv应用开发与实现
一、背景与简介 YOLO(You Only Look Once)是一种流行的实时目标检测系统,其核心思想是将目标检测视为回归问题,从而可以在单个网络中进行端到端的训练。YOLOv作为该系列的最新版本,带来了更高的检测精度和更快的处理速…...
【C语言】熟悉文件基础知识
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 文件 为了数据持久化保存,使用文件,否则数据存储在内存中,程序退出,内存回收,数据就会丢失。 程序设计中&…...
信息系统安全与对抗-作业2
目录 1、使用自己姓名拼音创建一个账户, 并使用命令和图形化查看 2、使用自己拼音打头字母创建一个隐藏账户 ,并使用命令和图形化查看 3、使用命令启动 telnet 服务 4、使用命令打开防火墙 23 端口 5、熟悉LINUX系统,使用命令行创建用户…...
【软考高项】【计算专题】- 5 - 进度类 - 横道图/甘特图
一、知识点 1、基本定义 甘特图(Gantt chart )又称为横道图、条状图(Bar chart),通过条状图来显示项目各活动的进 度情况。以提出者亨利劳伦斯甘特( Henry Laurence Gantt)先生的名字命名。 目前许多文档工具都可以画甘特图。 (1)我的举例 …...
Ubuntu20.04使用XRDP安装原生远程桌面
Ubuntu20.04使用XRDP安装原生远程桌面 1.安装gnome桌面 # 如果没有更新过源缓存,先更新一下 sudo apt update# 安装gnome桌面 # 可选参数 --no-install-recommends,不安装推荐组件,减少安装时间和空间占用 sudo apt install ubuntu-desktop…...
uniapp:启动图 .9png 制作教程
1、工具安装:自行下载Android Studio 2、制作.9png 注意上图3条黑线的位置,意思是:标注黑线的位置可以进行缩放。 对其大多数启动图来说,标注以上3条黑线即可。...
NVMFS5113PLWFT1G汽车级功率MOSFET 60V 10A/64A满足AEC-Q101标准
AEC-Q101认证标准详细解读: AEC-Q101是一种汽车电子元件可靠性标准,由汽车电子委员会(Automotive Electronics Council,简称AEC)制定。该标准旨在确保在汽车环境中使用的电子元件具有足够的可靠性和耐久性。 AEC-Q10…...
Android内存泄漏排查实战:如何用dma_buf揪出Low Memory的元凶
Android内存泄漏排查实战:如何用dma_buf揪出Low Memory的元凶 当你的Android设备开始频繁弹出"内存不足"的警告,甚至出现应用闪退、系统卡顿等问题时,作为开发者需要立即警觉——这很可能不是简单的内存紧张,而是潜伏着…...
Vue3集成百度地图GL版:从自定义样式到动态轨迹绘制实战
1. Vue3集成百度地图GL版的前期准备 第一次在Vue3项目里用百度地图GL版时,我踩了不少坑。这里分享下最稳妥的集成方案,帮你避开那些我趟过的雷。首先得明白,百度地图GL版是基于WebGL技术的新一代地图API,相比传统版本性能更好、效…...
OpenClaw+Phi-3-vision-128k-instruct:个人知识库的自动化图文索引系统
OpenClawPhi-3-vision-128k-instruct:个人知识库的自动化图文索引系统 1. 为什么需要自动化图文索引 作为一名长期与各类技术文档打交道的开发者,我发现自己越来越陷入"资料沼泽"——电脑里堆满了PDF、PPT和截图,却总在关键时刻找…...
数字示波器原理与高级测量技术详解
1. 示波器基础概念与核心功能 示波器作为电子工程师最常用的测试仪器之一,其核心功能是捕捉和显示电信号随时间变化的波形。现代数字示波器(DSO)通过模数转换器(ADC)将模拟信号转换为数字信号进行处理和显示࿰…...
6款AI论文降重软件,智能改写与优化,显著提升原创度。
开头总结工具对比(技能4) �� 为帮助学生们快速选出最适合的AI论文工具,我从处理速度、降重效果和核心优势三个维度,对比了6款热门网站,数据基于实际使用案例: 工具名称 处理速度 降…...
OpenAI Assistants API 深度测评与开发指南
OpenAI Assistants API 深度测评与开发指南 第1章 核心概念与问题溯源:从“一次性对话API”到“智能助手构建引擎” 1.1 核心概念:什么是OpenAI Assistants API? 1.1.1 官方定义拆解 OpenAI Assistants API(以下简称“Assistants API”)是OpenAI在2023年11月发布的DevD…...
Qt Modbus 报文构建实战:QModbusRequest构造与sendRawRequest发送详解
1. Qt Modbus开发环境搭建与基础概念 在工业自动化领域,Modbus协议就像设备之间的"普通话",而Qt Modbus库则是我们与设备对话的翻译器。我刚开始接触这个领域时,花了一整天时间才搞明白如何正确发送一个简单的控制指令。下面分享我…...
功分器选型全解析:从参数到实战应用
1. 功分器基础:从参数理解到选型逻辑 功分器这个看似简单的射频器件,在实际工程选型时常常让新手工程师犯难。我第一次接触功分器时,就被各种参数搞得晕头转向——为什么同样是2分路功分器,有的标称3dB损耗,实测却是3.…...
Halcon卡尺直线检测避坑指南:参数设置与常见错误排查
Halcon卡尺直线检测避坑指南:参数设置与常见错误排查 在工业视觉检测领域,直线边缘的精准定位是许多项目的基础需求。Halcon作为行业标杆工具,其卡尺直线检测功能看似简单,却暗藏诸多参数陷阱。不少开发者在初次接触时࿰…...
【仅限前500名开放】自动驾驶C++算法性能审计清单(含17项ASAM OpenSCENARIO兼容性检测项+Clang-Tidy定制规则集)
第一章:自动驾驶C算法性能审计的工程意义与实施边界在L3及以上等级自动驾驶系统中,C算法模块(如感知融合、路径规划、控制执行)的毫秒级延迟波动或内存异常增长,可能直接导致安全临界事件。性能审计并非仅关注峰值吞吐…...
