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

基于SuperSocket搭建SocketServer服务

一、NuGet 包管理器中下载相关包

安装 SuperSocket.WebSocket.Server 包
image

二、启动SocketServer服务

注册启动WebSocket Server 服务方法
`
///


/// WebSocket服务器实例
///

private IHost? _webSocketServer;

///


/// 启动 WebSocket Server 服务
///

/// 监听端口
/// 监听IP地址
/// 取消令牌
/// 异步任务
public async Task WebSocketServerAsync(int port, IPAddress ip, CancellationToken cancellationToken = default)
{
try
{
_webSocketServer = WebSocketHostBuilder.Create()
.UseWebSocketMessageHandler(
async (session, message) => await HandleWebSocketMessageAsync(session, message.Message)
)
.ConfigureAppConfiguration((hostContext, configApp) =>
{
var config = new Dictionary<string, string>
{
["serverOptions:listeners:0:ip"] = ip.ToString(),
["serverOptions:listeners:0:port"] = port.ToString()
};
configApp.AddInMemoryCollection(config);
})
.Build();

    // 启动WebSocket服务器await _webSocketServer.RunAsync(cancellationToken);
}
catch (Exception ex)
{Console.WriteLine($"WebSocket服务器启动失败: {ex.Message}");
}

}
`

三、消息处理,通过反射加载对应请求处理方法

消息处理,通过反射加载对应请求处理方法

`
///


/// 方法缓存,用于存储反射获取的Socket相关方法
///

private Dictionary<string, MethodInfo> _webSocketMethodCache = new();

///


/// 存储所有连接的WebSocket会话
///

private readonly ConcurrentDictionary<string, WebSocketSession> _connectedSessions = new();

///


/// 处理 WebSocket 消息
///

/// WebSocket会话
/// WebSocket消息
/// 异步任务
private async Task HandleWebSocketMessageAsync(WebSocketSession session, string message)
{
// 确保会话已添加到连接列表
if (_connectedSessions.TryAdd(session.SessionID ?? Guid.NewGuid().ToString(), session))
{
Console.WriteLine($"新会话已连接: {session.SessionID}");
}
// 处理收到的消息
await OnWebSocketMessageAsync(session, message);
}

///


/// 处理接收到的 WebSocket 消息
///

/// WebSocket会话
/// WebSocket消息
/// 异步任务
private async Task OnWebSocketMessageAsync(WebSocketSession session, string message)
{
try
{
// Console.WriteLine($"收到消息: {message}");
JObject messageObject;
try
{
messageObject = JObject.Parse(message);
// TODO: 检查是否有topic属性
if (messageObject["topic"] != null)
{
// 根据不同的topic来处理不同的消息
string topic = messageObject["topic"].ToString();

            // TODO: 先检查topic和op对应的方法是否缓存MethodInfo memberInfo = null;if (_webSocketMethodCache.TryGetValue(topic, out memberInfo)){// 当前的方法已经在缓存中,直接调用memberInfo.Invoke(this, new object[] { session, message });return;}// TODO: 没有找到对应的方法,则进行反射var methods = GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);foreach (var method in methods){var attributes = method.GetCustomAttributes(typeof(WebSocketMessageAttribute), false);if (attributes.Length > 0){var attribute = attributes[0] as WebSocketMessageAttribute;if (attribute.Topic == topic){// TODO: 把method进行缓存,免得每次都需要反射_webSocketMethodCache.Add(topic, method);// TODO: 把method添加到Dictionary中,key是topic,value是methodmethod.Invoke(this, new object[] { session, message });}}}}}catch (Exception ex){Console.WriteLine($"检查是否有topic属性,{ex.Message}");}}
catch (Exception ex)
{Console.WriteLine($"处理WebSocket消息时出错: {ex.Message}");
}

}

`

`
///


/// WebSocket消息属性
///

public class WebSocketMessageAttribute : Attribute
{
public string Topic { get; }

 public WebSocketMessageAttribute(string topic){Topic = topic;}

}
`

/// <summary> /// 获取Joint状态,则返回joint值 /joint_states /// </summary> /// <param name="session"></param> /// <param name="message"></param> /// <returns></returns> [WebSocketMessage("/joint_states")] private async Task JointStatesAsync(WebSocketSession session, string message) { try { // TODO: 获取并解析消息文本 Console.WriteLine(message); } catch (Exception ex) { Console.WriteLine($"获取/joint_states报错,{ex.Message}"); } }

http://www.jsqmd.com/news/159236/

相关文章:

  • 企业级AI开发工具终极部署指南:高效赋能开发团队
  • PyTorch-CUDA镜像中Jupyter Notebook密码设置方法
  • Input Remapper终极配置指南:从入门到精通的全流程解析
  • 2025年靠谱的气体探测器生产厂家排行榜,诚信的气体探测器靠谱厂家推荐 - myqiye
  • Jupyter Notebook无法启动?检查你的PyTorch-CUDA镜像配置
  • 2025年口碑好、实力强、诚信的瓷砖免拆改色品牌企业推荐 - 工业品网
  • Transformer入门:一文读懂《Attention Is All You Need》
  • 可视化运行管理:运行监控管理规范
  • 京东云鼎生态掘金指南:新空间知识库,破解店铺增长与API对接的密码
  • Docker镜像源优化建议:优先选择PyTorch-CUDA-v2.7基础环境
  • AI决策时代,星链引擎GEO优化:让品牌成为AI优先推荐的核心选择
  • AI 驱动代码编辑器: Cursor 简介
  • Bcrypt.NET 密码安全实战指南:构建坚不可摧的.NET数据防护体系
  • DBeaver多线程数据导入配置指南:大幅提升导入效率的实战技巧
  • me_cleaner:彻底清除Intel ME安全隐患的终极方案
  • 技术架构:如何让多智能体“吵出”更优解——竞合机制的关键设计模式
  • 计算机视觉任务首选:PyTorch-CUDA-v2.7支持YOLO和CNN
  • 基于PyTorch-CUDA-v2.7的深度学习环境搭建全流程解析
  • LocalAI Docker 容器化部署指南
  • 云原生应用性能测试:应对高并发场景‌
  • HTTP协议为什么要3次握手,而不是2次/4次握手
  • Flutter file_selector 库在鸿蒙(OHOS)平台的适配实践与深度解析
  • 【干货收藏】大模型Agent工作流全解析,从入门到精通,小白也能看懂
  • PyTorch-CUDA-v2.7镜像SSH连接教程:远程开发更便捷
  • StableAnimator:5分钟快速上手CVPR2025最佳人体动画生成框架
  • Jupyter Notebook直连PyTorch-CUDA环境,科研效率大幅提升
  • 人人开源前端组件库实战指南:基于Vue2和Element UI的高效开发方案
  • doocs/md编辑器搜索功能完整指南:3分钟从入门到精通
  • 2025年巴拿马置业移民公司排名,信誉好的巴拿马购房移民公司全解析 - 工业品网
  • 五款城市通勤合资混动SUV精选:20万以内智能驾驶辅助系统推荐