asp.net core 使用SignalR推送消息,本篇文章实现两个功能:1、简单在线聊天;2、推送消息给指定用户。
一、使用SignalR前准备工作:
1、使用Visual Studio Code 创建mvc项目
2、mvc项目添加Microsoft.AspNetCore.SignalR引用
3、下载signalr.js,放在wwwroot文件下任意位置
4、自定义类继承Hub,如下:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using web.Model;
namespace web.Core
{
public class MyHub : Hub
{
//发送消息--发送给所有连接的客户端
public Task SendMessage(string msg)
{
return Clients.All.SendAsync("ReceiveMessage", msg);
}
//发送消息--发送给指定用户
public Task SendPrivateMessage(string userId, string message)
{
return Clients.User(userId).SendAsync("ReceiveMessage", message);
}
}
}
4、mvc项目配置 SignalR 服务、设置 SignalR 路由
在Startup.cs中的ConfigureServices方法添加代码
services.AddSignalR();
在Startup.cs中的Configure方法添加SignalR路由配置代码,路由指向自定义类MyHub,如下:
app.UseSignalR(routes=>{
routes.MapHub<MyHub>("/MyHub");
});
5、客户端js中创建连接、启动连接代码,如下:
//创建连接对象connection
const signalr_connection = new signalR.HubConnectionBuilder()
.withUrl("/MyHub")
.configureLogging(signalR.LogLevel.Information)
.build();
//启动connection
signalr_connection.start()
.then(function(){
console.log("连接成功");
}).catch(function(ex){
console.log("连接失败"+ex);
//SignalR JavaScript 客户端不会自动重新连接,必须编写代码将手动重新连接你的客户端
setTimeout(() => start(), 5000);
});
async function start() {
try {
await signalr_connection.start();
console.log("connected");
} catch (err) {
console.log(err);
setTimeout(() => start(), 5000);
}
};
这里准备工作差不多了。
二、简单在线聊天功能:
1、在HomeController 创建一个Action,如下:
public IActionResult Chat()
{
return View();
}
html代码如下:
<ul class="form-group" id="messagesListUl" style="margin-bottom:20px"></ul>
<form>
<div class="form-group">
<label for="username">姓名:</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<div class="form-group">
<label for="msgcontent">内容:</label>
<textarea rows="5" cols="20" id="msgcontent" name="msgcontent" class="form-control"></textarea>
</div>
<input type="button" onclick="btnSendMsg()" value="发送">
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/signalr/dist/signalr.js"></script>
<script type="text/javascript">
//创建连接对象connection
const signalr_connection = new signalR.HubConnectionBuilder()
.withUrl("/MyHub")
.configureLogging(signalR.LogLevel.Information)
.build();
//启动connection
signalr_connection.start()
.then(function(){
console.log("连接成功");
}).catch(function(ex){
console.log("连接失败"+ex);
//SignalR JavaScript 客户端不会自动重新连接,必须编写代码将手动重新连接你的客户端
setTimeout(() => start(), 5000);
});
async function start() {
try {
await signalr_connection.start();
console.log("connected");
} catch (err) {
console.log(err);
setTimeout(() => start(), 5000);
}
};
signalr_connection.onclose(async () => {
start();
});
//绑定事件("ReceiveMessage"和服务器端的SendMessage方法中的第一个参数一致)
signalr_connection.on("ReceiveMessage", function(data) {
var msgObj = JSON.parse(data);//json串转对象
const li = document.createElement("li");
li.textContent = msgObj.name + " : " + msgObj.message;
document.getElementById("messagesListUl").appendChild(li);
});
//发送消息
function btnSendMsg(){
var username = $.trim($("#username").val());
var msgcontent = $.trim($("#msgcontent").val());
var msgObj={};
msgObj.name=username;
msgObj.message=msgcontent;
var jsonstr=JSON.stringify(msgObj);//对象转json串
console.log(jsonstr);
signalr_connection.invoke("SendMessage", jsonstr).catch(err => console.error("发送失败:"+err.toString()));
}
</script>
说明:
a、signalr_connection.on() 绑定事件时,第一个参数对应MyHub类中的SendMessage方法中“Clients.All.SendAsync("ReceiveMessage", msg)”的第一个参数。
b、signalr_connection.invoke()发送消息时,第一个参数对应MyHub类中的SendMessage方法名。
效果如下: