using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SignalR.Draw.Core.SignalR;
namespace SignalR.Draw.Core
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//添加SignalR
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
//添加SignalR
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SignalR.Draw.Core.SignalR
{
public class ChatHub : Hub<IHubClient>
{
private const string BROADCAST = "broadcast";
/// <summary>
/// client调用发送
/// </summary>
/// <param name="roomName"></param>
/// <param name="userName"></param>
/// <param name="content"></param>
/// <returns></returns>
public async Task Send(string roomName, string userName, string content)
{
await SendToClient(roomName, userName, content);
}
/// <summary>
/// 连接成功
/// </summary>
/// <returns></returns>
public override Task OnConnectedAsync()
{
var connectionId = Context.ConnectionId;
return base.OnConnectedAsync();
}
/// <summary>
/// 失去连接
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public override Task OnDisconnectedAsync(Exception exception)
{
//todo
return base.OnDisconnectedAsync(exception);
}
/// <summary>
/// 进入房间
/// </summary>
/// <param name="roomName"></param>
/// <param name="userName"></param>
/// <param name="content"></param>
/// <returns></returns>
public async Task InRoom(string roomName, string userName, string content)
{
var connectionId = Context.ConnectionId;
await Groups.AddToGroupAsync(connectionId, roomName);
await SendToClient(roomName, userName, content);
}
/// <summary>
/// 离开房间
/// </summary>
/// <param name="roomName"></param>
/// <param name="userName"></param>
/// <param name="content"></param>
/// <returns></returns>
public async Task OutRoom(string roomName, string userName, string content)
{
var connectionId = Context.ConnectionId;
await SendToClient(roomName, userName, content);
await Groups.RemoveFromGroupAsync(connectionId, roomName);
}
/// <summary>
/// 发送到Client
/// </summary>
/// <param name="roomName"></param>
/// <param name="userName"></param>
/// <param name="content"></param>
/// <returns></returns>
private async Task SendToClient(string roomName, string userName, string content)
{
if (roomName == BROADCAST)//广播
{
await Clients.All.ReceiveAsync(new Message { UserName = userName, RoomName = string.Empty, Content = content });
}
else
{
await Clients.Groups<IHubClient>(roomName).ReceiveAsync(new Message { UserName = userName, RoomName = roomName, Content = content });
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SignalR.Draw.Core.SignalR
{
public interface IHubClient
{
/// <summary>
/// 发送消息到客户端
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
Task ReceiveAsync(Message message);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SignalR.Draw.Core.SignalR
{
public class Message
{
/// <summary>
/// 房间名
/// 注意:广播=""
/// </summary>
public string RoomName { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
}
}
@{
ViewData["Title"] = "Home Page";
}
<style type="text/css">
.house {
margin: 0;
padding: 0;
}
.house .room {
margin: 50px 10px;
padding: 0;
list-style-type: none;
width: 200px;
height: 200px;
float: left;
}
.house .room .board {
margin: 0;
padding: 0 0 0 10px;
border: 1px solid black;
width: 200px;
height: 200px;
text-align: left;
overflow: auto;
}
.house .room .name {
width: 200px;
height: 200px;
}
.house .room .input {
width: 200px;
height: 50px;
}
.house .room .input input {
width: 100%;
}
</style>
<script src="~/lib/signalr/signalr.js"></script>
<script type="text/javascript">
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
connection.on("ReceiveAsync", function (message) {
console.log(message);
receive(message.roomName, message.userName, message.content);
});
connection.start().catch(function (err) {
return console.error(err.toString());
}).then(function () {
inRoom("broadcast", myName, "加入房间");
});
</script>
<script type="text/javascript">
var myName = prompt("enter your name", "man");
$(function () {
$("#txtMyName").html(myName);
$("[name=content]").keydown(function (event) {
//send
if (event.keyCode == "13") {
var content = $(this).val();
var roomName = $(this).parent().parent().attr("name");
send(roomName, myName, content);
$(this).val("");
}
});
$("[name=in]").click(function () {
var roomName = $(this).parent().parent().attr("name");
inRoom(roomName, myName, "加入房间");
$(this).prop("disabled", "disabled");
$(this).siblings("button").prop("disabled","");
});
$("[name=out]").click(function () {
var roomName = $(this).parent().parent().attr("name");
outRoom(roomName, myName, "离开房间");
$(this).prop("disabled", "disabled");
$(this).siblings("button").prop("disabled", "");
});
})
//send data
function send(room, userName, content) {
connection.invoke("Send", room, userName, content).catch(function (err) {
return console.error(err.toString());
});
}
//receive data
function receive(room, userName, content) {
renderContent(room, userName, content);
}
//out room
function outRoom(room, userName, content) {
connection.invoke("OutRoom", room, userName, content).catch(function (err) {
return console.error(err.toString());
});
}
//in room
function inRoom(room, userName, content) {
connection.invoke("InRoom", room, userName, content).catch(function (err) {
return console.error(err.toString());
});
}
//render data
function renderContent(room, userName, content) {
console.log(content);
if (room == "") room = "broadcast";
if (room == "broadcast" && content != "离开房间" && content != "加入房间") {
$("[name=" + room + "] .board").append("<div>" + userName + " :" + content + "</div>")
}
else {
$("[name=" + room + "] .board").append("<div>" + userName + " :" + content + "</div>")
}
}
</script>
<div class="text-center">
<ul class="house">
<li class="room" name="broadcast">
<div class="board">
</div>
<div class="input">
<input name="content" placeholder="say:" />
</div>
<div class="name">
广播
</div>
</li>
</ul>
<div style="clear:both"></div>
<ul class="house">
@for (int i = 1; i < 10; i++)
{
<li class="room" name="room@(i)">
<div class="board">
</div>
<div class="input">
<input name="content" placeholder="say:" />
</div>
<div class="name">
房间@(i)<button name="in">加入</button><button name="out" disabled>离开</button>
</div>
</li>
}
</ul>
</div>
最终运行效果:
git开源地址:https://github.com/XXXXX34/SignalR.Draw.Core