维护一个网站要多少钱,免费云手机无限时间版,vs2015做网站的后端,seo全网推广之前写的SignalR通信#xff0c;是基于.net6api#xff0c;BS和CS进行通信的。
.net6API使用SignalRvue3聊天WPF聊天_signalr wpf_故里2130的博客-CSDN博客
今天写一篇关于CS客户端的SignalR通信#xff0c;后台服务使用.net6api 。其实和之前写的差不多#xff0c;主要在…之前写的SignalR通信是基于.net6apiBS和CS进行通信的。
.net6API使用SignalRvue3聊天WPF聊天_signalr wpf_故里2130的博客-CSDN博客
今天写一篇关于CS客户端的SignalR通信后台服务使用.net6api 。其实和之前写的差不多主要在于服务端以后台进程的方式存在而客户端以exe方式存在其实代码都一样只是生成的方式不一样。 一、服务端
1.首先建立一个.net6的webapi服务端 2.Program.cs
using SignalRServerApi.Controllers;namespace SignalRServerApi
{public class Program{public static void Main(string[] args){var builder WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddControllers();// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();builder.Services.AddSignalR(); //增加AddSignalRstring[] urls new[] { http://localhost:3000 }; //此处一定要写指定的ip地址地址是前端的ip地址坑了我1天的时间builder.Services.AddCors(options options.AddDefaultPolicy(builder builder.WithOrigins(urls).AllowAnyMethod().AllowAnyHeader().AllowCredentials()));var app builder.Build();// Configure the HTTP request pipeline.if (app.Environment.IsDevelopment()){app.UseSwagger();app.UseSwaggerUI();}app.UseCors(); //增加跨域问题app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.MapHubChatHub(/api/chat); //前端访问的地址2边要统一就行了app.Run();}}
}
3.ChatHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Collections.Concurrent;namespace SignalRServerApi.Controllers
{public class ChatHub : Hub{private static Dictionarystring, string dicUsers new Dictionarystring, string();public override Task OnConnectedAsync() //登录{Console.WriteLine($ID:{Context.ConnectionId} 已连接); //控制台记录var cid Context.ConnectionId;//根据id获取指定客户端var client Clients.Client(cid);//向指定用户发送消息//client.SendAsync(Self, cid);//像所有用户发送消息Clients.All.SendAsync(ReceivePublicMessageLogin, ${cid}加入了聊天室); //界面显示登录return base.OnConnectedAsync();}public override Task OnDisconnectedAsync(Exception? exception) //退出的时候{Console.WriteLine($ID:{Context.ConnectionId} 已断开);var cid Context.ConnectionId;//根据id获取指定客户端var client Clients.Client(cid);//向指定用户发送消息//client.SendAsync(Self, cid);//像所有用户发送消息Clients.All.SendAsync(ReceivePublicMessageLogin, ${cid}离开了聊天室); //界面显示登录return base.OnDisconnectedAsync(exception);}/// summary/// 向所有客户端发送消息/// /summary/// param nameuser/param/// param namemessage/param/// returns/returnspublic async Task SendPublicMessage(string user, string message){ //string user,await Clients.All.SendAsync(ReceivePublicMessage, user, message); //ReceiveMessage 提供给客户端使用}/// summary/// 用户登录密码就不判断了/// /summary/// param nameuserId/parampublic void Login(string userId) //对应前端的invoke{if (!dicUsers.ContainsKey(userId)){dicUsers[userId] Context.ConnectionId;}Console.WriteLine(${userId}登录成功ConnectionId{Context.ConnectionId});//向所有用户发送当前在线的用户列表Clients.All.SendAsync(dicUsers, dicUsers.Keys.ToList()); //对应前端的on}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{//如果当前用户不在线正常是保存数据库等上线时加载暂时不做处理}}}}4.生成方式
选择Windows应用程序 5.运行
运行后服务是以进程的方式存在 6.效果
此时需要注意代码的这个地址 当然IP和端口都可以修改的也可以增加网页显示根据业务而定。 二、客户端
1.首先建立一个.net6的wpf客户端 2.安装Microsoft.AspNetCore.SignalR.Client 3.建立界面
界面代码
Window x:ClassSignalRClient.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:SignalRClientmc:IgnorabledTitleMainWindow Height450 Width800GridStackPanel OrientationVerticalStackPanel OrientationHorizontalTextBlock账号:/TextBlockTextBox Nameuser Width300 Height20 Margin0,5/TextBox/StackPanelStackPanel OrientationHorizontalTextBlock密码:/TextBlockTextBox Namepassword Width300 Height20 Margin0,5/TextBox/StackPanelStackPanel OrientationHorizontal Button NamebtnLogin Width50 Height20 Margin0,5 ClickbtnLogin_Click登录/Button/StackPanelStackPanel OrientationHorizontalTextBlock发送给某人:/TextBlockTextBox NametoUser Width300 Height20 Margin0,5 /TextBox/StackPanelStackPanel OrientationHorizontalTextBlock发送内容:/TextBlockTextBox Namecontent Width300 Height20 Margin0,5/TextBox/StackPanelStackPanel OrientationHorizontalButton NamebtnSendAll Width100 Height20 Margin0,5 ClickbtnSendAll_Click发送所有人/ButtonButton NamebtnSendOne Width100 Height20 Margin0,5 ClickbtnSendOne_Click发送到个人/Button/StackPanelRichTextBox Height100 NamertbtxtFlowDocumentParagraphRun Text//Paragraph/FlowDocument/RichTextBox/StackPanel/Grid
/Window4.后台代码
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace SignalRClient
{/// summary/// Interaction logic for MainWindow.xaml/// /summarypublic partial class MainWindow : Window{private HubConnection hubConnection;public MainWindow(){InitializeComponent();//rtbtxt.AppendText(4444);}private void btnLogin_Click(object sender, RoutedEventArgs e){//此处和VUE3界面是一样的参照写就行了。//1.初始化InitInfo();//2.连接Link();//3.监听Listen();//4.登录Login();}/// summary/// 初始化/// /summaryprivate void InitInfo(){hubConnection new HubConnectionBuilder().WithUrl(http://127.0.0.1:5000/api/chat, (opt) {opt.HttpMessageHandlerFactory (message) {if (message is HttpClientHandler clientHandler)// bypass SSL certificateclientHandler.ServerCertificateCustomValidationCallback (sender, certificate, chain, sslPolicyErrors) { return true; };return message;};}).WithAutomaticReconnect().Build();hubConnection.KeepAliveInterval TimeSpan.FromSeconds(5);}Liststring LoginUser;string msgContent;/// summary/// 监听数据的变化/// /summaryprivate void Listen(){hubConnection.OnListstring(dicUsers, msg {LoginUser msg;string s string.Empty;foreach (string item in msg){s item 用户登录 Environment.NewLine;}rtbtxt.AppendText(s);}); //匿名方法 真实环境中此处使用的是属性变化不要使用赋值的方式hubConnection.Onstring(ReceivePublicMessageLogin, msg { msgContent msg; rtbtxt.AppendText(msg Environment.NewLine); });hubConnection.Onstring, string(ReceivePublicMessage, (user, msg) { msgContent msg; rtbtxt.AppendText(user 说 msg Environment.NewLine); }); //匿名方法hubConnection.Onstring(ChatInfo, msg { msgContent msg; rtbtxt.AppendText(msg Environment.NewLine); });}/// summary/// 连接/// /summaryprivate async void Link(){try{await hubConnection.StartAsync();}catch (Exception ex){MessageBox.Show(ex.Message);}}private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){// 在这里添加你的证书验证逻辑// 返回true表示验证通过返回false表示验证失败// 例如你可以添加自定义的证书验证逻辑来允许不受信任的证书return true;}private void Login(){hubConnection.InvokeAsync(Login, user.Text);}private void btnSendAll_Click(object sender, RoutedEventArgs e){hubConnection.InvokeAsync(SendPublicMessage, user.Text, content.Text);}private void btnSendOne_Click(object sender, RoutedEventArgs e){hubConnection.InvokeAsync(ChatOne, user.Text, toUser.Text, content.Text);}}
}这里需要注意 一起运行不会报错但是单独运行会报错
The SSL connection could not be established, see inner exception
需要在初始化InitInfo()方法中增加HttpMessageHandlerFactory即可解决。 5.效果 此时后台的服务以进行的方式存在然后可以和客户端进行通信其实和之前写的是一样的只是生成方式不同而已。 源码
https://download.csdn.net/download/u012563853/88061397