移动端应用与网站互联控制咨询:基于React与C#的飞镖板应用
关于React移动端+C# Web飞镖板实时同步方案的解答
一、是否可以通过Socket实现实时同步?
完全可以,而且是这类实时交互场景的最优方案之一。在你的技术栈下,推荐使用ASP.NET Core SignalR——它是微软官方基于WebSocket、Server-Sent Events等协议封装的实时通信框架,完美适配C#后端,同时提供了React(包括React Native)的客户端库,能快速实现移动端与Web端的分数同步:
- 移动端点击飞镖板区域后,获取对应分数,通过SignalR客户端发送到C#后端Hub;
- 后端Hub收到分数后,广播给所有订阅的Web端客户端;
- Web端监听广播事件,实时更新分数展示UI。
二、联机大厅与互联相关的实现思路及教程方向
以下是可落地的分步实现指南:
1. 基础实时通信搭建
C#后端部分
- 创建ASP.NET Core Web应用,在
Program.cs中注册SignalR服务:builder.Services.AddSignalR();,并配置端点:app.MapHub<DartHub>("/dartHub");; - 定义Hub类,处理客户端连接、分数接收与广播逻辑。
React端(移动端+Web端)
- 安装SignalR客户端包:
npm install @microsoft/signalr; - 建立与后端Hub的连接,监听分数更新事件,实现分数发送方法。
2. 联机大厅功能扩展
- 房间管理:在Hub中用集合(如
Dictionary<string, List<string>>)维护房间ID与连接ID的映射,提供JoinRoom、LeaveRoom方法,让用户加入指定房间; - 定向广播:发送分数时指定房间ID,仅向该房间内的客户端广播分数,实现多房间隔离;
- 状态同步:在Hub中维护房间内的用户列表、当前分数等状态,客户端加入房间时同步这些状态,实现大厅信息展示。
核心代码示例
C# Hub代码
using Microsoft.AspNetCore.SignalR; using System.Collections.Generic; using System.Threading.Tasks; public class DartHub : Hub { // 存储房间与连接ID的映射 private static readonly Dictionary<string, List<string>> _rooms = new Dictionary<string, List<string>>(); /// <summary> /// 加入指定房间 /// </summary> public async Task JoinRoom(string roomId) { if (!_rooms.ContainsKey(roomId)) { _rooms[roomId] = new List<string>(); } _rooms[roomId].Add(Context.ConnectionId); await Groups.AddToGroupAsync(Context.ConnectionId, roomId); // 通知房间内其他用户有新用户加入 await Clients.Group(roomId).SendAsync("UserJoined", Context.ConnectionId); } /// <summary> /// 发送分数到指定房间 /// </summary> public async Task SendScore(string roomId, int score) { // 向房间内所有客户端广播分数更新 await Clients.Group(roomId).SendAsync("ScoreUpdated", score); } /// <summary> /// 断开连接时移除房间映射 /// </summary> public override Task OnDisconnectedAsync(System.Exception exception) { foreach (var room in _rooms) { if (room.Value.Contains(Context.ConnectionId)) { room.Value.Remove(Context.ConnectionId); if (room.Value.Count == 0) { _rooms.Remove(room.Key); } break; } } return base.OnDisconnectedAsync(exception); } }
React端代码
import { useEffect, useState } from 'react'; import { HubConnectionBuilder } from '@microsoft/signalr'; const DartBoardSync = () => { const [connection, setConnection] = useState(null); const [currentScore, setCurrentScore] = useState(0); const roomId = "dart-room-001"; // 可由用户输入或生成 useEffect(() => { // 建立与后端Hub的连接 const newConnection = new HubConnectionBuilder() .withUrl('/dartHub') .withAutomaticReconnect() .build(); setConnection(newConnection); }, []); useEffect(() => { if (connection) { connection.start() .then(() => { console.log('Connected to SignalR Hub'); // 加入指定房间 connection.invoke('JoinRoom', roomId); // 监听分数更新事件 connection.on('ScoreUpdated', (score) => { setCurrentScore(score); }); }) .catch(err => console.error('Connection error: ', err)); } }, [connection, roomId]); // 模拟移动端点击飞镖板获取分数 const handleDartClick = (score) => { if (connection) { connection.invoke('SendScore', roomId, score) .catch(err => console.error('Send score error: ', err)); } }; return ( <div> {/* Web端展示分数 */} <h2>当前分数:{currentScore}</h2> {/* 移动端飞镖板点击区域(示例) */} <div onClick={() => handleDartClick(20)} style={{width: '100px', height: '100px', backgroundColor: 'red'}}> 点击得20分 </div> </div> ); }; export default DartBoardSync;
内容的提问来源于stack exchange,提问作者Bence Bakos
相关产品推荐
相关产品推荐

