diff --git a/backend/IM_API/Hubs/ChatHub.cs b/backend/IM_API/Hubs/ChatHub.cs
new file mode 100644
index 0000000..6211181
--- /dev/null
+++ b/backend/IM_API/Hubs/ChatHub.cs
@@ -0,0 +1,27 @@
+using IM_API.Interface.Services;
+using Microsoft.AspNetCore.SignalR;
+using System.Security.Claims;
+
+namespace IM_API.Hubs
+{
+ public class ChatHub:Hub
+ {
+ private IJWTService _JWTService;
+ public ChatHub(IJWTService jWTService)
+ {
+ _JWTService = jWTService;
+ }
+
+ public override Task OnConnectedAsync()
+ {
+ var userIdStr = Context.User.FindFirstValue(ClaimTypes.NameIdentifier);
+ int userId = int.Parse(userIdStr);
+ Console.WriteLine(userId);
+ return base.OnConnectedAsync();
+ }
+ public async Task SendMessage(string user,string message)
+ {
+ await Clients.Caller.SendAsync("ReceiveMessage", "qwfqwfqw","test");
+ }
+ }
+}
diff --git a/backend/IM_API/IM_API.csproj b/backend/IM_API/IM_API.csproj
index d2ea7fb..7d9b73e 100644
--- a/backend/IM_API/IM_API.csproj
+++ b/backend/IM_API/IM_API.csproj
@@ -13,6 +13,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/backend/IM_API/Program.cs b/backend/IM_API/Program.cs
index 8c2eab4..f4d4a6f 100644
--- a/backend/IM_API/Program.cs
+++ b/backend/IM_API/Program.cs
@@ -1,5 +1,6 @@
using IM_API.Configs;
+using IM_API.Hubs;
using IM_API.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
@@ -42,7 +43,6 @@ namespace IM_API
policy.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyHeader()
- .AllowAnyOrigin()
.AllowAnyOrigin();
});
});
@@ -104,6 +104,8 @@ namespace IM_API
var app = builder.Build();
+ app.UseCors();
+
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
@@ -120,6 +122,8 @@ namespace IM_API
app.MapControllers();
+ app.MapHub("/chat").RequireCors();
+
app.Run();
}
}
diff --git a/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.metadata.v9.bin b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.metadata.v9.bin
new file mode 100644
index 0000000..515c4f7
Binary files /dev/null and b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.metadata.v9.bin differ
diff --git a/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.projects.v9.bin b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.projects.v9.bin
new file mode 100644
index 0000000..5ecf14e
Binary files /dev/null and b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.projects.v9.bin differ
diff --git a/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.strings.v9.bin b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.strings.v9.bin
new file mode 100644
index 0000000..8f10075
Binary files /dev/null and b/backend/SignalRTest/.vs/ProjectEvaluation/signalrtest.strings.v9.bin differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/CodeChunks.db b/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/CodeChunks.db
new file mode 100644
index 0000000..e3b7b86
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/CodeChunks.db differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/SemanticSymbols.db b/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/SemanticSymbols.db
new file mode 100644
index 0000000..2c135d3
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/CopilotIndices/17.14.995.13737/SemanticSymbols.db differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/DesignTimeBuild/.dtbcache.v2 b/backend/SignalRTest/.vs/SignalRTest/DesignTimeBuild/.dtbcache.v2
new file mode 100644
index 0000000..e04f082
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/DesignTimeBuild/.dtbcache.v2 differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/1c4991db-4934-4d46-a536-c061f2b8883a.vsidx b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/1c4991db-4934-4d46-a536-c061f2b8883a.vsidx
new file mode 100644
index 0000000..6dd8938
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/1c4991db-4934-4d46-a536-c061f2b8883a.vsidx differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/54b38182-994e-4e72-9485-38a2e159fade.vsidx b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/54b38182-994e-4e72-9485-38a2e159fade.vsidx
new file mode 100644
index 0000000..2a3f669
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/54b38182-994e-4e72-9485-38a2e159fade.vsidx differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/ec86fa31-80ef-4881-99f5-8f1b6a13c76c.vsidx b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/ec86fa31-80ef-4881-99f5-8f1b6a13c76c.vsidx
new file mode 100644
index 0000000..b19a5c2
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/FileContentIndex/ec86fa31-80ef-4881-99f5-8f1b6a13c76c.vsidx differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/v17/.futdcache.v2 b/backend/SignalRTest/.vs/SignalRTest/v17/.futdcache.v2
new file mode 100644
index 0000000..8c2ce01
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/v17/.futdcache.v2 differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/v17/.suo b/backend/SignalRTest/.vs/SignalRTest/v17/.suo
new file mode 100644
index 0000000..ed5641e
Binary files /dev/null and b/backend/SignalRTest/.vs/SignalRTest/v17/.suo differ
diff --git a/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.backup.json b/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.backup.json
new file mode 100644
index 0000000..05a3c84
--- /dev/null
+++ b/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.backup.json
@@ -0,0 +1,57 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form",
+ "RelativeMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|c:\\users\\nanxun\\documents\\im\\backend\\signalrtest\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 200,
+ "SelectedChildIndex": 1,
+ "Children": [
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Form1.cs [\u8BBE\u8BA1]",
+ "DocumentMoniker": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeDocumentMoniker": "Form1.cs",
+ "ToolTip": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs [\u8BBE\u8BA1]",
+ "RelativeToolTip": "Form1.cs [\u8BBE\u8BA1]",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-12-06T07:30:28.584Z",
+ "EditorCaption": " [\u8BBE\u8BA1]"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "Form1.cs",
+ "DocumentMoniker": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeDocumentMoniker": "Form1.cs",
+ "ToolTip": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeToolTip": "Form1.cs",
+ "ViewState": "AgIAAA4AAAAAAAAAAAAuwBQAAAAJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-12-06T07:28:32.613Z",
+ "EditorCaption": ""
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.json b/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.json
new file mode 100644
index 0000000..05a3c84
--- /dev/null
+++ b/backend/SignalRTest/.vs/SignalRTest/v17/DocumentLayout.json
@@ -0,0 +1,57 @@
+{
+ "Version": 1,
+ "WorkspaceRootPath": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\",
+ "Documents": [
+ {
+ "AbsoluteMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form",
+ "RelativeMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|c:\\users\\nanxun\\documents\\im\\backend\\signalrtest\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{266B86EE-17CF-4DD4-84C8-8CE3E2640A70}|SignalRTest.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ }
+ ],
+ "DocumentGroupContainers": [
+ {
+ "Orientation": 0,
+ "VerticalTabListWidth": 256,
+ "DocumentGroups": [
+ {
+ "DockedWidth": 200,
+ "SelectedChildIndex": 1,
+ "Children": [
+ {
+ "$type": "Bookmark",
+ "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Form1.cs [\u8BBE\u8BA1]",
+ "DocumentMoniker": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeDocumentMoniker": "Form1.cs",
+ "ToolTip": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs [\u8BBE\u8BA1]",
+ "RelativeToolTip": "Form1.cs [\u8BBE\u8BA1]",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-12-06T07:30:28.584Z",
+ "EditorCaption": " [\u8BBE\u8BA1]"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "Form1.cs",
+ "DocumentMoniker": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeDocumentMoniker": "Form1.cs",
+ "ToolTip": "C:\\Users\\nanxun\\Documents\\IM\\backend\\SignalRTest\\Form1.cs",
+ "RelativeToolTip": "Form1.cs",
+ "ViewState": "AgIAAA4AAAAAAAAAAAAuwBQAAAAJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-12-06T07:28:32.613Z",
+ "EditorCaption": ""
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/backend/SignalRTest/Form1.Designer.cs b/backend/SignalRTest/Form1.Designer.cs
new file mode 100644
index 0000000..5878f90
--- /dev/null
+++ b/backend/SignalRTest/Form1.Designer.cs
@@ -0,0 +1,206 @@
+namespace SignalRTest
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ button1 = new Button();
+ button2 = new Button();
+ txtUrl = new TextBox();
+ TokenTxt = new TextBox();
+ UrlLab = new Label();
+ label2 = new Label();
+ Historylab = new RichTextBox();
+ label3 = new Label();
+ MethodTxt = new TextBox();
+ label4 = new Label();
+ SendMsg = new Button();
+ ParamsTxt = new TextBox();
+ label5 = new Label();
+ toolTip1 = new ToolTip(components);
+ SuspendLayout();
+ //
+ // button1
+ //
+ button1.Location = new Point(143, 294);
+ button1.Name = "button1";
+ button1.Size = new Size(94, 29);
+ button1.TabIndex = 0;
+ button1.Text = "连接";
+ button1.UseVisualStyleBackColor = true;
+ button1.Click += button1_Click;
+ //
+ // button2
+ //
+ button2.Location = new Point(278, 294);
+ button2.Name = "button2";
+ button2.Size = new Size(94, 29);
+ button2.TabIndex = 1;
+ button2.Text = "断开连接";
+ button2.UseVisualStyleBackColor = true;
+ button2.Click += button2_Click;
+ //
+ // txtUrl
+ //
+ txtUrl.Location = new Point(112, 39);
+ txtUrl.Name = "txtUrl";
+ txtUrl.Size = new Size(303, 27);
+ txtUrl.TabIndex = 2;
+ txtUrl.Text = "http://localhost:5202/chat";
+ //
+ // TokenTxt
+ //
+ TokenTxt.Location = new Point(553, 39);
+ TokenTxt.Name = "TokenTxt";
+ TokenTxt.Size = new Size(125, 27);
+ TokenTxt.TabIndex = 3;
+ //
+ // UrlLab
+ //
+ UrlLab.AutoSize = true;
+ UrlLab.Location = new Point(31, 42);
+ UrlLab.Name = "UrlLab";
+ UrlLab.Size = new Size(38, 20);
+ UrlLab.TabIndex = 4;
+ UrlLab.Text = "URL";
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(475, 42);
+ label2.Name = "label2";
+ label2.Size = new Size(69, 20);
+ label2.TabIndex = 5;
+ label2.Text = "登录凭证";
+ //
+ // Historylab
+ //
+ Historylab.Location = new Point(112, 85);
+ Historylab.Name = "Historylab";
+ Historylab.Size = new Size(303, 188);
+ Historylab.TabIndex = 6;
+ Historylab.Text = "";
+ //
+ // label3
+ //
+ label3.AutoSize = true;
+ label3.Location = new Point(16, 165);
+ label3.Name = "label3";
+ label3.Size = new Size(69, 20);
+ label3.TabIndex = 7;
+ label3.Text = "消息历史";
+ //
+ // MethodTxt
+ //
+ MethodTxt.Location = new Point(553, 182);
+ MethodTxt.Name = "MethodTxt";
+ MethodTxt.Size = new Size(125, 27);
+ MethodTxt.TabIndex = 8;
+ toolTip1.SetToolTip(MethodTxt, "后端hub内对应方法名,大小写敏感");
+ //
+ // label4
+ //
+ label4.AutoSize = true;
+ label4.Location = new Point(475, 182);
+ label4.Name = "label4";
+ label4.Size = new Size(39, 20);
+ label4.TabIndex = 9;
+ label4.Text = "方法";
+ toolTip1.SetToolTip(label4, "后端hub内对应方法名,大小写敏感");
+ //
+ // SendMsg
+ //
+ SendMsg.Location = new Point(705, 244);
+ SendMsg.Name = "SendMsg";
+ SendMsg.Size = new Size(94, 29);
+ SendMsg.TabIndex = 10;
+ SendMsg.Text = "发送";
+ SendMsg.UseVisualStyleBackColor = true;
+ SendMsg.Click += SendMsg_Click;
+ //
+ // ParamsTxt
+ //
+ ParamsTxt.Location = new Point(553, 246);
+ ParamsTxt.Name = "ParamsTxt";
+ ParamsTxt.Size = new Size(125, 27);
+ ParamsTxt.TabIndex = 11;
+ toolTip1.SetToolTip(ParamsTxt, "hub方法对应参数,请使用以下格式:[参数1,参数2,参数3,...]");
+ //
+ // label5
+ //
+ label5.AutoSize = true;
+ label5.Location = new Point(475, 253);
+ label5.Name = "label5";
+ label5.Size = new Size(39, 20);
+ label5.TabIndex = 12;
+ label5.Text = "参数";
+ toolTip1.SetToolTip(label5, "hub方法对应参数,请使用以下格式:[参数1,参数2,参数3,...]");
+ //
+ // Form1
+ //
+ AutoScaleDimensions = new SizeF(9F, 20F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(800, 450);
+ Controls.Add(label5);
+ Controls.Add(ParamsTxt);
+ Controls.Add(SendMsg);
+ Controls.Add(label4);
+ Controls.Add(MethodTxt);
+ Controls.Add(label3);
+ Controls.Add(Historylab);
+ Controls.Add(label2);
+ Controls.Add(UrlLab);
+ Controls.Add(TokenTxt);
+ Controls.Add(txtUrl);
+ Controls.Add(button2);
+ Controls.Add(button1);
+ Name = "Form1";
+ Text = "SignalR调试工具";
+ Load += Form1_Load;
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private Button button1;
+ private Button button2;
+ private TextBox txtUrl;
+ private TextBox TokenTxt;
+ private Label UrlLab;
+ private Label label2;
+ private RichTextBox Historylab;
+ private Label label3;
+ private TextBox MethodTxt;
+ private Label label4;
+ private Button SendMsg;
+ private TextBox ParamsTxt;
+ private Label label5;
+ private ToolTip toolTip1;
+ }
+}
diff --git a/backend/SignalRTest/Form1.cs b/backend/SignalRTest/Form1.cs
new file mode 100644
index 0000000..8d7a9b6
--- /dev/null
+++ b/backend/SignalRTest/Form1.cs
@@ -0,0 +1,143 @@
+using Microsoft.AspNetCore.SignalR.Client;
+using System.Text.Json;
+using System.Windows.Forms;
+
+namespace SignalRTest
+{
+ public partial class Form1 : Form
+ {
+ private HubConnection _connection;
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private async void button1_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ _connection = new HubConnectionBuilder()
+ .WithUrl(txtUrl.Text, options =>
+ {
+ options.AccessTokenProvider = () =>
+ Task.FromResult(TokenTxt.Text);
+ })
+ .WithAutomaticReconnect()
+ .Build();
+
+ _connection.On("ReceiveMessage", (user, message) =>
+ {
+ Historylab.Invoke(new Action(() =>
+ {
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Green;
+ Historylab.AppendText("Ϣ" + message + "\n");
+ }));
+ });
+
+ _connection.Reconnecting += (ex) =>
+ {
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("..." + "\n");
+ return System.Threading.Tasks.Task.CompletedTask;
+ };
+
+ _connection.Reconnected += (id) =>
+ {
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("ɹ" + "\n");
+ return System.Threading.Tasks.Task.CompletedTask;
+ };
+
+ await _connection.StartAsync();
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("ӳɹ" + "\n");
+ }
+ catch (Exception ex)
+ {
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("ʧܣ" + ex.Message + "\n");
+ }
+ }
+
+ private async void button2_Click(object sender, EventArgs e)
+ {
+ if (_connection != null)
+ {
+ await _connection.StopAsync();
+ await _connection.DisposeAsync();
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("Ͽӣ" + "\n");
+ }
+ }
+
+ private async void SendMsg_Click(object sender, EventArgs e)
+ {
+ if (_connection == null || _connection.State != HubConnectionState.Connected)
+ {
+ // ƶ굽ıĩβ
+ Historylab.SelectionStart = Historylab.TextLength;
+ Historylab.SelectionLength = 0;
+
+ Historylab.SelectionColor = Color.Blue;
+ Historylab.AppendText("ӣ" + "\n");
+ return;
+ }
+
+ try
+ {
+ var method = MethodTxt.Text.Trim();
+ var paramText = ParamsTxt.Text.Trim();
+
+ object[] parameters = string.IsNullOrWhiteSpace(paramText)
+ ? Array.Empty