为了实现前后端实时通讯,之前用的websocket。
今天想用SignalR实现,发现这个用起来更好点。
1.首先创建asp.net core web 项目。(我用的是Visual studio 2022 Framework .net 6.0)
创建Hubs目录,新建ChatHub.cs文件
ChatHub.cs 内容如下
using CompoundingDevice.Common;
using CompoundingDevice.Communication;
using CompoundingDevice.Helper;
using Microsoft.AspNetCore.SignalR;
using System.Diagnostics;
using System.Reflection;
namespace CompoundingDevice.Hubs
{
public class ChatHub : Hub
{
//被客户端调用
public async Task CallByClient(string user, string message)
{
string msg;
await Clients.All.SendAsync("OnHubMessage", user, message);
//TcpSupersocket.GetInstance().Send(message);
}
//被客户端调用,有并返回值
public string CallByClientResult(string user, string message)
{
string msg="result";
await Clients.All.SendAsync("OnHubMessage", user, message);
return msg;
}
//调用客户端
public async Task CallClient(string user, string message)
{
string msg;
await Clients.All.SendAsync("OnHubMessage", " call Client " + message);
msg = $"ChatHub CallClient url = {GlobalValue.Host} port = {GlobalValue.Port} user = {user} message = {message}";
LogHelper.Info(msg);
Debug.WriteLine(msg);
await Task.Delay(1);
string s = MethodInfo.GetCurrentMethod()?.Name + "";
}
//全员发送
public async Task CallAllClient(string user, string message)
{
string msg;
await Clients.All.SendAsync("OnHubMessage", " call Client " + message);
}
//向自身以外发送
public async Task CallOtherClient(string user, string message)
{
string msg;
await Clients.Others.SendAsync("OnHubMessage", " call Client " + message);
}
}
}
在program.cs 中加入
builder.Services.AddSignalR();
app.MapHub<ChatHub>(“/chatHub”);
using CompoundingDevice.Communication;
using CompoundingDevice.Helper;
using CompoundingDevice.Hubs;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddLogging(cfg =>
{
cfg.AddLog4Net(new Log4NetProviderOptions()
{
Log4NetConfigFileName = "ConfigFile/log4net.config",
Watch = true
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");
app.Run();
新建chat.js 这个代码是微软官网的
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;
connection.on("OnHubMessage", function (user, message) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
// We can assign user-supplied strings to an element's textContent because it
// is not interpreted as markup. If you're assigning in any other way, you
// should be aware of possible script injection concerns.
li.textContent = `${user} says ${message}`;
});
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButtonNew").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("CallByClient", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
html代码内容
@page
@model CompoundingDevice.Pages.SignalRModel
@{
}
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-2">User</div>
<div class="col-4"><input type="text" id="userInput" value="SignalRClient"/></div>
</div>
<div class="row">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" id="messageInput" value='{"CMD":"SignalR Message"}' /></div>
</div>
<div class="row"> </div>
<div class="row">
<div class="col-6">
<input type="button" id="sendButton" value="Send Message" />
</div>
<div class="col-7">
<input type="button" id="sendButtonNew" value="Send Message New" />
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
signalr.js 我就直接拷贝微软官网内容了
可以编写应用程序和Hub中心通讯。这里可以是winform,wpf,控制台
using CompoundingDevice.Common;
using CompoundingDevice.Helper;
using Microsoft.AspNetCore.SignalR.Client;
using System.Diagnostics;
namespace CompoundingDevice.Communication
{
public class SignalRMsg
{
public static SignalRMsg? Instance;
static HubConnection? connection;
public static SignalRMsg GetInstance()
{
if (Instance == null)
{
Instance = new SignalRMsg();
}
return Instance;
}
public void Connect()
{
string SignalRIP = AppSettingsHelper.Configuration["SignalR:IP"];
int SignalRPort = int.Parse(AppSettingsHelper.Configuration["SignalR:Port"]);
string url = $"http://{SignalRIP}:{SignalRPort}/chatHub";
Debug.WriteLine($" SignalR URL = {url}");
connection = new HubConnectionBuilder()
.WithUrl(new Uri(url))
//.WithUrl(new Uri("http://localhost:8100/chatHub"))
.WithAutomaticReconnect()
.Build();
connection.Closed += async (e) =>
{
await Task.Delay(new Random().Next(0, 5) * 1000);
await connection.StartAsync();
};
connection.On<string, string>("OnHubMessage", (s1, s2) => RecvMSG(s1, s2));
connection.StartAsync();
}
public static async void CallClient(string user, string message)
{
await connection.InvokeAsync("CallClient", user, message);
string msg = $"SignalRMsg CallClient 发送数据 user = {user} message = {message}";
LogHelper.Info(msg);
}
}
}
以上代码敲过之后,发现SignalR使用还是很方便。可以理解为 客户端和中心的通讯,这样不但简化了开发,还扩展了用途。
1. 微软官网参考
版权声明:本文为easyboot原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。