Android studio—socketIO库return与emit的使用

news2025/4/24 0:20:18

文章目录

      • 一、Socket.IO库简单使用说明
        • 1. 后端 Flask + Flask-SocketIO
        • 2. Android 客户端集成 Socket.IO
        • 3. 布局文件
        • 注意事项
      • 二、接受服务器消息的二种方法
        • 1. 客户端接收通过 `emit` 发送的消息
          • 功能
          • 使用场景
          • 后端代码(Flask-SocketIO)
          • 客户端代码(Android Studio,Java)
        • 2. 客户端接收通过 `return` 发送的响应
          • 功能
          • 使用场景
          • 后端代码(Flask-SocketIO)
          • 客户端代码(Android Studio,Java)
        • 4. 二者的区别
      • 拓展:room与namespace
        • 命名空间(Namespace)
          • 功能示例
        • 房间(Rooms)
          • 功能示例
        • 总结
        • 拓展:


Socket.IO 是一个流行的实时通信库,支持 WebSocket 和其他回退机制(如长轮询),能够在客户端和服务器之间实现低延迟的双向通信。

一、Socket.IO库简单使用说明

1. 后端 Flask + Flask-SocketIO

首先,确保你的 Flask 后端已经安装了 Flask-SocketIO。你可以通过以下命令安装:

pip install Flask Flask-SocketIO

以下是一个简单的 Flask 后端示例代码:

from flask import Flask
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
socketio = SocketIO(app)

@app.route('/')
def index():
    return "Hello, World!"

@socketio.on('message')
def handle_message(msg):
    print('Received message: ' + msg)
    emit('response', 'Echo: ' + msg, broadcast=True)

if __name__ == '__main__':
    socketio.run(app, debug=True)
2. Android 客户端集成 Socket.IO

在 Android Studio 中,你需要添加 Socket.IO 的依赖。在 build.gradle 文件中添加以下内容:

dependencies {
    implementation 'io.socket:socket.io-client:1.4.0'
}

确保你的应用有网络权限。在 AndroidManifest.xml 文件中添加以下内容:

<uses-permission android:name="android.permission.INTERNET" />

以下是一个简单的 Android 客户端示例:

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class MainActivity extends AppCompatActivity {
    private Socket socket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            socket = IO.socket("http://yourserver.com/socket.io");
            socket.connect();

            socket.on("response", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            TextView messagesView = findViewById(R.id.messagesView);
                            messagesView.append((String) args[0] + "\n");
                        }
                    });
                }
            });

            Button sendButton = findViewById(R.id.sendButton);
            sendButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EditText messageInput = findViewById(R.id.messageInput);
                    String message = messageInput.getText().toString();
                    if (!message.isEmpty()) {
                        socket.emit("message", message);
                        messageInput.setText("");
                    }
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        socket.disconnect();
    }
}
3. 布局文件

res/layout/activity_main.xml 中定义一个简单的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/messageInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Type a message" />

    <Button
        android:id="@+id/sendButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send" />

    <TextView
        android:id="@+id/messagesView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Messages will appear here"
        android:textSize="16sp" />

</LinearLayout>

socket.onsocket.emit

特性socket.onsocket.emit
功能监听来自服务器的事件向服务器发送事件
方向从服务器到客户端从客户端到服务器
回调注册回调函数以处理接收到的事件可选地注册回调函数以接收服务器的响应
使用场景接收服务器推送的消息,如通知、广播等发送请求到服务器,如提交数据、请求信息等
注意事项
  1. 服务器地址:确保在 Android 客户端中使用的服务器地址与 Flask 后端的地址一致。
  2. 网络权限:确保在 AndroidManifest.xml 中添加了网络权限。
  3. 线程安全:在回调函数中更新 UI 时,确保使用 runOnUiThread

二、接受服务器消息的二种方法

  • emit
    • 后端:使用 emit 发送事件和数据。
    • 客户端:通过 socket.on 监听事件并接收数据。
  • return
    • 后端:在事件处理函数中使用 return 发送响应。
    • 客户端:通过 emit 方法的回调函数接收响应。
1. 客户端接收通过 emit 发送的消息

当后端使用 emit 发送消息时,客户端可以通过 socket.on 监听对应的事件来接收消息。

功能
  • 显式发送事件emit 可以发送自定义事件,并携带数据。
  • 广播或单播:可以指定发送给所有客户端,或者特定的客户端。
使用场景
  • 广播消息:向所有连接的客户端发送消息。
  • 单播消息:向特定的客户端发送消息。
  • 复杂交互:需要发送多个事件或不同类型的数据时。
后端代码(Flask-SocketIO)
from flask import Flask
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app)

@socketio.on('client_message')
def handle_client_message(data):
    print("Received message:", data)
    emit('server_message', 'Hello from Server!')  # 使用 emit 发送消息

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000)
客户端代码(Android Studio,Java)
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class MainActivity extends AppCompatActivity {
    private Socket mSocket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            mSocket = IO.socket("http://your-server-address:5000");
            mSocket.connect();

            // 监听服务器通过 emit 发送的消息
            mSocket.on("server_message", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    String message = (String) args[0];
                    runOnUiThread(() -> {
                        Toast.makeText(MainActivity.this, "Received via emit: " + message, Toast.LENGTH_SHORT).show();
                    });
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSocket.disconnect();
        mSocket.off("server_message");
    }
}
2. 客户端接收通过 return 发送的响应

当后端使用 return 发送响应时,客户端可以通过 emit 方法的回调函数接收响应。

功能
  • 返回响应:直接返回一个值或字符串。
  • 简单交互:适用于简单的场景,客户端不需要复杂的消息交互。
使用场景
  • 简单响应:客户端只需要一个简单的响应,例如确认消息已接收。
  • 快速反馈:快速返回一个结果,不需要额外的事件处理。
后端代码(Flask-SocketIO)
from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
socketio = SocketIO(app)

@socketio.on('client_message')
def handle_client_message(data):
    print("Received message:", data)
    return 'Server received your message!'  # 使用 return 发送响应

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000)
客户端代码(Android Studio,Java)
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class MainActivity extends AppCompatActivity {
    private Socket mSocket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            mSocket = IO.socket("http://your-server-address:5000");
            mSocket.connect();

            // 发送消息并接收通过 return 发送的响应
            mSocket.emit("client_message", "Hello from Android!", new Emitter.Ack() {
                @Override
                public void call(Object... args) {
                    if (args.length > 0) {
                        String response = (String) args[0];
                        runOnUiThread(() -> {
                            Toast.makeText(MainActivity.this, "Received via return: " + response, Toast.LENGTH_SHORT).show();
                        });
                    }
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSocket.disconnect();
    }
}
4. 二者的区别
特性emitreturn
功能显式发送事件,携带数据直接返回响应
方向从服务器到客户端从服务器到客户端
使用场景广播或单播消息,复杂交互简单响应,快速反馈
示例emit('server_message', 'Hello from Server!')return 'Server received your message!'
  • 如果你需要向客户端发送复杂的事件或广播消息,使用 emit
  • 如果客户端只需要一个简单的响应,使用 return

拓展:room与namespace

在 Flask-SocketIO 中,命名空间(Namespace)和房间(Rooms)是两个非常重要的功能,它们可以更好地组织和管理实时通信。

命名空间(Namespace)

命名空间允许在同一个 Socket.IO 服务器上创建多个独立的通信通道。每个命名空间都可以有自己的事件和逻辑,互不干扰。这在大型应用中非常有用,可以将不同的功能模块分开,例如聊天功能和通知功能。

功能示例
from flask_socketio import emit

@socketio.on('message', namespace='/chat')
def handle_chat_message(msg):
    emit('message', msg, broadcast=True, namespace='/chat')

@socketio.on('notification', namespace='/notifications')
def handle_notification(msg):
    emit('notification', msg, broadcast=True, namespace='/notifications')

在上面的代码中,/chat/notifications 是两个不同的命名空间,分别用于处理聊天消息和通知。

房间(Rooms)

房间是命名空间的进一步细分,允许将用户分组,以便向特定的用户组发送消息。这在聊天室、多人游戏等场景中非常有用。

功能示例
from flask_socketio import join_room, leave_room

@socketio.on('join')
def on_join(data):
    username = data['username']
    room = data['room']
    join_room(room)
    send(username + ' has entered the room.', to=room)

@socketio.on('leave')
def on_leave(data):
    username = data['username']
    room = data['room']
    leave_room(room)
    send(username + ' has left the room.', to=room)

在上面的代码中,join_roomleave_room 函数用于管理用户加入和离开房间。send 函数的 to 参数用于指定消息发送到的房间。

总结
  • 命名空间:用于创建独立的通信通道,适合将不同的功能模块分开。
  • 房间:用于将用户分组,适合向特定用户组发送消息。

通过合理使用命名空间和房间,可以构建更加模块化和高效的实时通信应用。

拓展:

room功能实现用户之间消息的发送

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2341111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu24.04安装ROS2问题

1&#xff0c;根据官方指导安装&#xff0c;安装到步骤&#xff1a; sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 时遇到问题。导致sudo apt update一直报错&#xff1a; 找了几天的资料…

【图问答】DeepSeek-VL 论文阅读笔记

《DeepSeek-VL: Towards Real-World Vision-Language Understanding》 1. 摘要/引言 基于图片问答&#xff08;Visual Question Answering&#xff0c;VQA&#xff09;的任务 2. 模型结构 和 三段式训练 1&#xff09;使用 SigLIP 和 SAM 作为混合的vision encoder&#xf…

【专题刷题】滑动窗口(二):水果成篮,所有字母异位词,乘积小于 K 的子数组

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

深入理解React中的Props与State:核心区别与最佳实践

在React开发中&#xff0c;props和state是构建交互式UI的两大基石。许多React初学者常常混淆这两者的概念&#xff0c;导致组件设计出现反模式。本文将全面剖析props与state的本质区别&#xff0c;通过实际场景说明它们的适用边界&#xff0c;并分享高效管理组件数据的实践经验…

STM32单片机入门学习——第46节: [14-1] WDG看门狗

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.23 STM32开发板学习——第46节: [14-1] WDG看门狗 前言开发板说明引用解答和科普一、…

n8n 中文系列教程_05.如何在本机部署/安装 n8n(详细图文教程)

n8n 是一款强大的开源工作流自动化工具&#xff0c;可帮助你连接各类应用与服务&#xff0c;实现自动化任务。如果你想快速体验 n8n 的功能&#xff0c;本机部署是最简单的方式。本教程将手把手指导你在 Windows 或 MacOS 上通过 Docker 轻松安装和运行 n8n&#xff0c;无需服务…

2025第十六届蓝桥杯python B组满分题解(详细)

目录 前言 A: 攻击次数 解题思路&#xff1a; 代码&#xff1a; B: 最长字符串 解题思路&#xff1a; 代码&#xff1a; C: LQ图形 解题思路&#xff1a; 代码&#xff1a; D: 最多次数 解题思路&#xff1a; 代码&#xff1a; E: A * B Problem 解题思路&…

Kafka 面试,java实战贴

面试问题列表 Kafka的ISR机制是什么&#xff1f;如何保证数据一致性&#xff1f; 如何实现Kafka的Exactly-Once语义&#xff1f; Kafka的Rebalance机制可能引发什么问题&#xff1f;如何优化&#xff1f; Kafka的Topic分区数如何合理设置&#xff1f; 如何设计Kafka的高可用跨…

linux多线(进)程编程——(9)信号量(一)

前言 在找到了共享内存存在的问题后&#xff0c;进程君父子着手开始解决这些问题。他们发明了一个新的神通——信号量。 信号量 信号量是一个计数器&#xff0c;用于管理对共享资源的访问权限。主要特点包括&#xff1a; &#xff08;1&#xff09;是一个非负整数 &#xff…

PFLM: Privacy-preserving federated learning with membership proof证明阅读

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

图片转base64 - 加菲工具 - 在线转换

图片转base64 - 加菲工具 先进入“加菲工具” 网 打开 https://www.orcc.top&#xff0c; 选择 “图片转base64”功能 选择需要转换的图片 复制 点击“复制”按钮&#xff0c;即可复制转换好的base64编码数据&#xff0c;可以直接用于img标签。

opencv 对图片的操作

对图片的操作 1.图片镜像旋转&#xff08;cv2.flip()&#xff09;2 图像的矫正 1.图片镜像旋转&#xff08;cv2.flip()&#xff09; 图像的旋转是围绕一个特定点进行的&#xff0c;而图像的镜像旋转则是围绕坐标轴进行的。图像的镜像旋转分为水平翻转、垂直翻转、水平垂直翻转…

LabVIEW数据采集与传感系统

开发了一个基于LabVIEW的智能数据采集系统&#xff0c;该系统主要通过单片机与LabVIEW软件协同工作&#xff0c;实现对多通道低频传感器信号的有效采集、处理与显示。系统的设计旨在提高数据采集的准确性和效率&#xff0c;适用于各种需要高精度和低成本解决方案的工业场合。 项…

【Easylive】​​Gateway模块 bootstrap.yml 解析

【Easylive】项目常见问题解答&#xff08;自用&持续更新中…&#xff09; 汇总版 Gateway模块 bootstrap.yml 常规解析 该配置文件定义了 Spring Cloud Gateway 的核心配置&#xff0c;包括 环境配置、服务注册、动态路由规则 等。以下是逐项解析&#xff1a; 1. 基础配…

matlab 环形单层柱状图

matlab 环形单层柱状图 matlab 环形单层柱状图 matlab 环形单层柱状图 图片 图片 【图片来源粉丝】 我给他的思路是&#xff1a;直接使用风玫瑰图可以画出。 rose_bar 本次我的更新和这个有些不同&#xff01;是环形柱状图&#xff0c;可调节细节多&#xff1b; 只需要函数…

文献×汽车 | 基于 ANSYS 的多级抛物线板簧系统分析

板簧系统是用于减弱或吸收动态系统中发生的应力、应变、偏转和变形等破坏性因素的机械结构。板簧系统可能对外力产生不同的响应&#xff0c;具体取决于其几何结构和材料特性。板簧系统的计算机辅助分析对于高精度确定系统的变形特性和结构特性至关重要。 在这项工作中&#xff…

RHCE 练习二:通过 ssh 实现两台主机免密登录以及 nginx 服务通过多 IP 区分多网站

一、题目要求 1.配置ssh实现A&#xff0c;B主机互相免密登录 2.配置nginx服务&#xff0c;通过多ip区分多网站 二、实验 实验开始前需准备两台 linux 主机便于充当服务端以及客户端&#xff0c;两台主机 IP 如下图&#xff1a; 实验1&#xff1a;配置 ssh 实现 A&#xff0…

瑞吉外卖-分页功能开发中的两个问题

1.分页功能-前端页面展示显示500 原因&#xff1a;项目启动失败 解决&#xff1a;发现是Category实体类中&#xff0c;多定义了一个删除字段&#xff0c;但是我数据库里面没有is_deleted字段&#xff0c;导致查询数据库失败&#xff0c;所以会导致500错误。因为类是从网上其他帖…

工业物联网安全网关 —— 安全OTA升级签名验证

这里写目录标题 工业物联网安全网关 —— 安全OTA升级签名验证一、项目背景与简介1.1 背景介绍1.2 OTA升级的安全挑战1.3 项目目标二、理论基础与关键技术2.1 数字签名基础2.2 OTA升级签名验证原理2.3 关键技术与安全算法三、系统架构设计3.1 系统模块划分3.2 系统架构图(Merm…

探索 Flowable 后端表达式:简化流程自动化

什么是后端表达式&#xff1f; 在 Flowable 中&#xff0c;后端表达式是一种强大的工具&#xff0c;用于在流程、案例或决策表执行期间动态获取或设置变量。它还能实现自定义逻辑&#xff0c;或将复杂逻辑委托…… 后端表达式在 Flowable 的后端运行&#xff0c;无法访问前端…