当前位置: 首页 > news >正文

Android studio—socketIO库的emit与return的使用

文章目录

      • 一、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. 二者的区别
      • 拓展:通过emit实现向特定客户端发送单播消息功能
        • 1. Flask-SocketIO 后端代码
          • 后端代码
        • 2. Android Studio Java 客户端代码
          • 客户端代码
        • 3. 代码说明


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, emitapp = 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;@Overrideprotected 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() {@Overridepublic void call(Object... args) {runOnUiThread(new Runnable() {@Overridepublic 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() {@Overridepublic 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();}}@Overrideprotected 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"><EditTextandroid:id="@+id/messageInput"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="Type a message" /><Buttonandroid:id="@+id/sendButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Send" /><TextViewandroid: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, emitapp = 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;@Overrideprotected 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() {@Overridepublic 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();}}@Overrideprotected void onDestroy() {super.onDestroy();mSocket.disconnect();mSocket.off("server_message");}
}
2. 客户端接收通过 return 发送的响应

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

功能
  • 返回响应:直接返回一个值或字符串。
  • 简单交互:适用于简单的场景,客户端不需要复杂的消息交互。
使用场景
  • 简单响应:客户端只需要一个简单的响应,例如确认消息已接收。
  • 快速反馈:快速返回一个结果,不需要额外的事件处理。
后端代码(Flask-SocketIO)
from flask import Flask
from flask_socketio import SocketIOapp = 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;@Overrideprotected 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() {@Overridepublic 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();}}@Overrideprotected void onDestroy() {super.onDestroy();mSocket.disconnect();}
}
4. 二者的区别
特性emitreturn
功能显式发送事件,携带数据直接返回响应
方向从服务器到客户端从服务器到客户端
使用场景广播或单播消息,复杂交互简单响应,快速反馈
示例emit('server_message', 'Hello from Server!')return 'Server received your message!'
  • 如果你需要向客户端发送复杂的事件或广播消息,使用 emit
  • 如果客户端只需要一个简单的响应,使用 return

拓展:通过emit实现向特定客户端发送单播消息功能

1. Flask-SocketIO 后端代码

在 Flask-SocketIO 中,可以通过 emit 方法向特定客户端发送单播消息。为此,需要在客户端连接时记录其 session ID,并在发送消息时指定该 session ID

后端代码
from flask import Flask, request
from flask_socketio import SocketIO, emitapp = Flask(__name__)
socketio = SocketIO(app)# 存储客户端的 session ID 和用户名的映射
clients = {}@socketio.on('connect')
def handle_connect():print('Client connected with session ID:', request.sid)# 假设客户端在连接时发送了一个用户名username = request.args.get('username')clients[request.sid] = usernameprint(f"Client {username} connected with session ID {request.sid}")@socketio.on('disconnect')
def handle_disconnect():print('Client disconnected with session ID:', request.sid)username = clients.pop(request.sid, None)if username:print(f"Client {username} disconnected")@socketio.on('client_message')
def handle_client_message(data):print("Received message:", data)# 假设客户端发送了一个消息和目标用户的用户名target_username = data.get('target')message = data.get('message')if target_username:# 查找目标客户端的 session IDfor sid, username in clients.items():if username == target_username:# 向目标客户端发送单播消息emit('server_message', f"Message from {clients[request.sid]}: {message}", room=sid)breakelse:# 如果没有指定目标用户,则广播消息emit('server_message', f"Broadcast message from {clients[request.sid]}: {message}", broadcast=True)if __name__ == '__main__':socketio.run(app, host='0.0.0.0', port=5000)
2. Android Studio Java 客户端代码

客户端需要连接到服务器,并发送消息。客户端可以通过 emit 方法发送消息,并指定目标用户的用户名。

客户端代码
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;public class MainActivity extends AppCompatActivity {private Socket mSocket;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);try {// 替换为你的服务器地址mSocket = IO.socket("http://your-server-address:5000");mSocket.connect();// 监听服务器消息mSocket.on("server_message", new Emitter.Listener() {@Overridepublic void call(Object... args) {String message = (String) args[0];runOnUiThread(() -> {Toast.makeText(MainActivity.this, "Received: " + message, Toast.LENGTH_SHORT).show();});}});// 发送消息给特定用户mSocket.emit("client_message", new JSONObject().put("target", "Bob") // 目标用户的用户名.put("message", "Hello Bob!")); // 消息内容} catch (Exception e) {e.printStackTrace();}}@Overrideprotected void onDestroy() {super.onDestroy();mSocket.disconnect();mSocket.off("server_message");}
}
3. 代码说明
  1. 后端代码

    • handle_connect 中,记录客户端的 session ID 和用户名。
    • handle_client_message 中,根据目标用户的用户名查找其 session ID,并通过 emit 向该客户端发送单播消息。
    • 如果没有指定目标用户,则广播消息给所有客户端。
  2. 客户端代码

    • 客户端通过 socket.on 监听服务器发送的 server_message 事件。
    • 客户端通过 socket.emit 向服务器发送消息,并指定目标用户的用户名。

相关文章:

  • JVM对象创建全过程
  • .net core 项目快速接入Coze智能体-开箱即用-第2节
  • langgraph框架之初识
  • AI 编程工具—如何在 Cursor 中集成使用 MCP工具
  • Banana Pi BPI-RV2 RISC-V 路由器开发板发售, 全球首款RISC-V路由器
  • STM32单片机入门学习——第41节: [12-1] Unix时间戳
  • SpringAI入门:对话机器人
  • docker 镜像
  • MySQL中高级语法
  • 解决 Spring Boot 多数据源环境下事务管理器冲突问题(非Neo4j请求标记了 @Transactional 尝试启动Neo4j的事务管理器)
  • polkitd服务无法启动导致docker无法启动问题解决
  • 海关总署广东:广东外贸一季度进出口2.14万亿元 同期增长4.2%
  • 2.2/Q2,Charls最新文章解读
  • 【Python爬虫基础篇】--2.模块解析
  • 07_Docker 资源限制
  • Jenkins的使用及Pipeline语法讲解
  • Android Studio 常见报错
  • 从零开始学Python游戏编程31-类3
  • 深入简出:KL散度、交叉熵、熵、信息量简介、交叉熵损失
  • ubuntu学习day3
  • 观察|英国航母再次部署印太,“高桅行动”也是“高危行动”
  • 中公教育薪酬透视:董监高合计涨薪122万,员工精简近三成
  • 格力电器去年净利增长一成:消费电器营收下滑4%,一季度净利增长26%
  • 加拿大温哥华一车辆冲撞人群,造成多人伤亡
  • 俄联邦安全局:俄军高级官员汽车爆炸案嫌疑人已被捕
  • 四川甘孜州白玉县发生4.9级地震,震源深度10千米