您的位置:首页 > 游戏 > 游戏 > C#利用SignalR实现通信事例Demo

C#利用SignalR实现通信事例Demo

2024/10/6 20:27:19 来源:https://blog.csdn.net/m0_55337678/article/details/139790377  浏览:    关键词:C#利用SignalR实现通信事例Demo

1.服务端安装SignalR的Nuget包

dotnet add package Microsoft.AspNet.SignalR --version 2.4.3

2.接下来,创建一个ChatHub类,它是SignalR通信的核心:

using Microsoft.AspNetCore.SignalR;public class ChatHub : Hub
{public static Dictionary<string, string> user = new();public void Connect(string key){if (user.ContainsKey(key)) { user.Remove(key); }user.Add(key,Context.ConnectionId);Console.WriteLine("("+ DateTime.Now +")客户端:"+ key + "上线成功!");}public async Task HandMsg(Chat chat){chat.time = DateTime.Now;ChatHandlerService handler;switch ( (Command) chat.cmd){case Command.PRIVATE:handler = new PrivateServiceImpl();await handler.execute(chat,user,Context,Clients);break; case Command.LINERADIO:handler = new LineradioServiceImpl();await handler.execute(chat, user, Context, Clients);break;}}
}
  •  这个是信息处理的提取ChatHandlerService
public interface ChatHandlerService
{Task execute(Chat chat,Dictionary<string, string> user,HubCallerContext context, IHubCallerClients clients);
}
  •  这个是单聊的具体实现
public class PrivateServiceImpl : ChatHandlerService
{public Task execute(Chat chat, Dictionary<string, string> user, HubCallerContext context, IHubCallerClients clients){if (user.ContainsKey(chat.target!)){string target = user[chat.target!];clients.Client(target).SendAsync("receive", chat);return Task.CompletedTask;}chat.message = "好友不在线";clients.Client(context.ConnectionId).SendAsync("receive", chat);return Task.CompletedTask;}
}
  • 这个是 通知全部在线的用户

public class LineradioServiceImpl : ChatHandlerService
{public async Task execute(Chat chat, Dictionary<string, string> user, HubCallerContext context, IHubCallerClients clients){await clients.All.SendAsync("receive", chat); }
}
  •  指令枚举
public enum Command
{PRIVATE = 300,GROUP = 400,LINERADIO = 500
}
  • 聊天模型 
public class Chat
{public string userKey { get; set; } = null!;public string? target { get; set; }public string? message { get; set; }public int type { get; set; }public int cmd { get; set; }public DateTime time { get; set; }
}

提示:Connect是连接的实例方法,当客户端成功后在回调使用此方法,HandMsg是我的信息处理方法,其中你可以不用我的service和实现层,直接在ChatHub类中使用你传入的数据就可以了。

3.在Program中使用

builder.Services.AddSignalR();builder.Services.AddCors(options =>
{options.AddDefaultPolicy(builder =>{builder.WithOrigins("http://localhost").AllowAnyHeader().WithMethods("GET", "POST").AllowCredentials();});
});app.MapHub<ChatHub>("/chathub");

提示:注意需要配置跨域

4.编写客服端代码

<!DOCTYPE html>
<html lang="">
<head><title>SignalR</title><script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.0/signalr.min.js"></script><meta charset="utf-8" />
</head>
<style>input {border-radius: 12px;padding: 5px 5px;}.sendButton {width:200px;border-radius: 12px;background: #3F95FF;padding: 6px 0;border: none;color: white;}
</style>
<body><h1>SignalR</h1>
<div style="display: flex;gap: 12px;flex-direction: column"><div><label for="target">发送给:</label><input type="text" id="target" /></div><div><label for="msg">信息:</label><input type="text" id="msg" /></div><div><button type="button" id="sendButton" class="sendButton">发送</button></div>
</div>
<div><ul id="messagesList"></ul>
</div><script>/*** 获取URL中的查询参数值** @param {string} name - 查询参数名* @returns {string|null} - 查询参数值,如果不存在则返回null*/function getQueryParam(name) {const urlParams = new URLSearchParams(window.location.search);return urlParams.get(name);}/*** 初始化SignalR连接*/const connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:7066/chathub").configureLogging(signalR.LogLevel.Information).build();/*** 监听服务器发送的消息** @param {object} res - 接收到的消息对象*/connection.on("receive", res => {const li = document.createElement("li");li.textContent = `${ res.userKey  }: ${res.message}`;document.getElementById("messagesList").appendChild(li);});/*** 启动SignalR连接,并调用Connect方法向服务器发送连接请求*/connection.start().then(() => {connection.invoke("Connect", getQueryParam("key")).catch(err => console.error(err.toString()));}).catch(function (err) {return console.error(err.toString());});/*** 发送按钮点击事件处理函数** @param {Event} event - 事件对象*/document.getElementById("sendButton").addEventListener("click", event => {const target = document.getElementById("target").value;const message = document.getElementById("msg").value;let sendMessage = {userKey: getQueryParam("key"),target: target,cmd: 300,message: message};/*** 调用服务器HandMsg方法发送消息*/connection.invoke("HandMsg", sendMessage).then(res => {const li = document.createElement("li");li.textContent = `我: ${message}`;document.getElementById("messagesList").appendChild(li);document.getElementById("msg").value = "";}).catch(err => console.error(err.toString()));event.preventDefault();});
</script>
</body>
</html>

浏览器需要在后面跟上参数Key 

http://localhost/?key=10086

 

5.完整代码地址

https://gitee.com/byte1026/signal-r.git

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com