<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title></title>
<link href="~/js/element-plus/index.css" rel="stylesheet" />
@* 顺序不能错*@
<script src="~/js/vue/vue.js"></script>
<script src="~/js/element-plus/index.js"></script>
<script src="~/js/element-plus/zh-cn.js"></script>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/websocket.js"></script>
<style scoped>
button {
margin: 5px;
}
input {
margin: 5px;
padding: 5px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 5px 0;
padding: 5px;
background-color: #f0f0f0;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<div id="app">
<div>
<h1>SignalR Chat</h1>
<input v-model="user" placeholder="Your name" />
<input v-model="message" placeholder="Type a message" @@keyup.enter="sendMessage" />
<button @@click="sendMessage">Send</button>
<ul>
<li v-for="(msg, index) in messages" :key="index">
<strong>{{ msg.user }}:</strong> {{ msg.message }}
</li>
</ul>
</div>
</div>
<script src="~/lib/microsoft/signalr/dist/browser/signalr.js"></script>
<script src="~/lib/microsoft/signalr/dist/browser/signalr.min.js"></script>
<script>
const { createApp, reactive, ref, toRefs, onMounted, nextTick, onUnmounted, getCurrentInstance } = Vue
const { ElMessageBox, ElMessage, ElLoading, ElNotification } = ElementPlus
const setup = {
setup() {
const user = ref('');
const message = ref('');
const messages = reactive([]);
var connection = new signalR.HubConnectionBuilder().withUrl("/ChatHub").build();
const startConnection = async () => {
try {
await connection.start();
console.log('SignalR Connected.');
} catch (err) {
console.error('SignalR Connection Error: ', err);
setTimeout(startConnection, 5000);
}
};
const sendMessage = async () => {
if (user.value && message.value) {
await connection.invoke('SendMessage', user.value, message.value);
message.value = '';
}
};
connection.on('ReceiveMessage', (user, message) => {
ElNotification({
title: 'Success',
message: user+ message,
type: 'success',
position: 'bottom-right',
duration: 10500,
})
messages.push({ user, message });
});
onMounted(() => {
startConnection();
});
onUnmounted(() => {
connection.stop();
});
return {
user,
message,
messages,
sendMessage,
};
}
}
createApp(setup).use(ElementPlus, { locale: ElementPlusLocaleZhCn }).mount("#app");
</script>
</body>
</html>
using Microsoft.AspNetCore.SignalR;
namespace Net6Test.Signalr
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
private static Dictionary<string, string> dicUsers = new Dictionary<string, string>();
public override Task OnConnectedAsync()
{
Console.WriteLine($"ID:{Context.ConnectionId} 已连接");
var cid = Context.ConnectionId;
var client = Clients.Client(cid);
Clients.All.SendAsync("ReceivePublicMessageLogin", $"{cid}加入了聊天室");
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception? exception)
{
Console.WriteLine($"ID:{Context.ConnectionId} 已断开");
var cid = Context.ConnectionId;
var client = Clients.Client(cid);
Clients.All.SendAsync("ReceivePublicMessageLogin", $"{cid}离开了聊天室");
return base.OnDisconnectedAsync(exception);
}
public async Task SendPublicMessage(string user, string message)
{
await Clients.All.SendAsync("ReceivePublicMessage", user, message);
}
public void Login(string userId)
{
if (!dicUsers.ContainsKey(userId))
{
dicUsers[userId] = Context.ConnectionId;
}
Console.WriteLine($"{userId}登录成功,ConnectionId={Context.ConnectionId}");
Clients.All.SendAsync("dicUsers", dicUsers.Keys.ToList());
}
public void ChatOne(string userId, string toUserId, string msg)
{
string newMsg = $"{userId}对你说{msg}";
if (dicUsers.ContainsKey(toUserId))
{
Clients.Client(dicUsers[toUserId]).SendAsync("ChatInfo", newMsg);
}
else
{
}
}
}
}
#region 添加SignalR
builder.Services.AddSignalR();
#endregion
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chatHub");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});