1、Program.cs里使用SignalR
//使用signalR
builder.Services.AddSignalR().AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
在 var app = builder.Build(); 之后
// 添加路由中间件
app.UseRouting();
//配置signalR
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<MessageHub>("/MessageHub");
});
2、新建MessageHub集线器
在Service层,新建Hub集线器
/// <summary>
/// 集线器
/// </summary>
public class MessageHub : Hub<IMessageHub>
{
ILogger<MessageHub> _logger;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="commonService"></param>
public MessageHub(ILogger<MessageHub> logger)
{
_logger = logger;
}
/// <summary>
/// 客户端连接服务端
/// </summary>
/// <returns></returns>
public override Task OnConnectedAsync()
{
var id = Context.ConnectionId;
_logger.LogInformation($"Client ConnectionId=> [[{id}]] Already Connection Server!");
return base.OnConnectedAsync();
}
/// <summary>
/// 客户端断开连接
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public override Task OnDisconnectedAsync(Exception? exception)
{
var id = Context.ConnectionId;
_logger.LogInformation($"Client ConnectionId=> [[{id}]] Already Close Connection Server!");
return base.OnDisconnectedAsync(exception);
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="user"></param>
/// <param name="message"></param>
/// <returns></returns>
// 定义了 SendMessage 方法,客户端可以调用该方法
public async Task SendMessage(string user, string message)
{
Console.WriteLine("Have one Data!" + message);
//收到user传来的消息,然后发送给所有客户端
string date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string msg = $"服务器消息: {date} {user} 说:{message}";
await Clients.All.SendMessage(msg);
}
}
3、在IServices层新建集线器接口
/// <summary>
/// 集线器
/// </summary>
public interface IMessageHub
{
/// <summary>
/// 发送消息
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
Task SendMessage(object message);
}
4、控制器新增消息控制器
/// <summary>
/// 消息发送
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class MessageController : ControllerBase
{
private readonly ILogger<MessageController> _logger;
/// <summary>
/// 发送消息服务器
/// </summary>
/// <param name="logger"></param>
public MessageController(ILogger<MessageController> logger)
{
_logger = logger;
}
/// <summary>
/// 发送消息给所有客户端
/// </summary>
/// <param name="date"></param>
/// <param name="hubContext"></param>
/// <returns></returns>
[HttpGet(Name = "SendMessage")]
public async Task SendMessage(string date, [FromServices] IHubContext<MessageHub, IMessageHub> hubContext)
{
var message = $"服务器消息: {date}";
await hubContext.Clients.All.SendMessage(message);
}
5、客户端连接服务器
客户端安装库
npm install @microsoft/signalr
客户端新建文件夹 utils和文件
main.ts引入SignalR
//引入signalR
import signalr from './utils/signalR'
挂载SignalR
//挂载signalr
app.config.globalProperties.$signalr = signalr.signal
客户端新建SignalR.js
import * as signalR from '@microsoft/signalr'
const url = 'http://localhost:5999/MessageHub'
const signal = new signalR.HubConnectionBuilder()
.withUrl(url, {
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.configureLogging(signalR.LogLevel.Information)
.build()
signal.on('SendMessage', (res) => {
console.log(res, '收到消息')
})
signal.start().then(() => {
if (window.Notification) {
if (Notification.permission === 'granted') {
console.log('允许通知')
} else if (Notification.permission !== 'denied') {
console.log('需要通知权限')
Notification.requestPermission((permission) => {
console.log('权限通知', permission)
})
} else if (Notification.permission === 'denied') {
console.log('拒绝通知')
}
} else {
console.error('浏览器不支持Notification')
}
console.log('连接成功')
})
signal.onclose((err) => {
console.log('连接已经断开 执行函数onclose', err)
})
export default {
signal
}
6、客户端使用SignalR
import { onMounted, getCurrentInstance,ref } from 'vue';
const message = ref('');
const signalr = getCurrentInstance()?.appContext.config.globalProperties.$signalr;
onMounted(()=>{
//获取signalr的通知
signalr.on('SendMessage', (receive: any) => {
//do something
});
})
const sendMessage = () => {
signalr.invoke('SendMessage', "your name" ,message.value);
};