diff --git a/JianGongYun.sln b/JianGongYun.sln
index b21d04c..f9fc656 100644
--- a/JianGongYun.sln
+++ b/JianGongYun.sln
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JianGongYun", "JianGongYun\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientDemo", "ClientDemo\ClientDemo.csproj", "{5C83270B-1086-494D-BCAF-0E773CC598AB}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WSDemo", "WSDemo\WSDemo.csproj", "{A748F095-84EF-4D1B-A1B1-842ADCD73D6C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -41,6 +43,18 @@ Global
{5C83270B-1086-494D-BCAF-0E773CC598AB}.Release|x64.Build.0 = Release|Any CPU
{5C83270B-1086-494D-BCAF-0E773CC598AB}.Release|x86.ActiveCfg = Release|Any CPU
{5C83270B-1086-494D-BCAF-0E773CC598AB}.Release|x86.Build.0 = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|x64.Build.0 = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Debug|x86.Build.0 = Debug|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|x64.ActiveCfg = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|x64.Build.0 = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|x86.ActiveCfg = Release|Any CPU
+ {A748F095-84EF-4D1B-A1B1-842ADCD73D6C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/JianGongYun/App.config b/JianGongYun/App.config
index d08a0bd..70c4087 100644
--- a/JianGongYun/App.config
+++ b/JianGongYun/App.config
@@ -6,5 +6,6 @@
+
diff --git a/JianGongYun/JianGongYun.csproj b/JianGongYun/JianGongYun.csproj
index 2276409..7144044 100644
--- a/JianGongYun/JianGongYun.csproj
+++ b/JianGongYun/JianGongYun.csproj
@@ -18,6 +18,7 @@
+
diff --git a/JianGongYun/Properties/launchSettings.json b/JianGongYun/Properties/launchSettings.json
index a4c6ce9..0613bfb 100644
--- a/JianGongYun/Properties/launchSettings.json
+++ b/JianGongYun/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"JianGongYun": {
"commandName": "Project",
- "commandLineArgs": "sznykt://--classhead|测试课程1|--classsubhead|测试章节1|--teacherid|12345678|--teachername|王大锤",
+ "commandLineArgs": "sznykt://--classhead|测试课程1|--classsubhead|测试章节1|--teacherid|1234_5678|--teachername|王大锤|endtime|MjAyMS0wMy0xOCAyMTo1MDowMA==",
"nativeDebugging": false
}
}
diff --git a/JianGongYun/Style/TRTCResource.xaml b/JianGongYun/Style/TRTCResource.xaml
index 8a0182c..de6d95f 100644
--- a/JianGongYun/Style/TRTCResource.xaml
+++ b/JianGongYun/Style/TRTCResource.xaml
@@ -71,7 +71,7 @@
-
+
diff --git a/JianGongYun/TRTC/LiveClassroom.cs b/JianGongYun/TRTC/LiveClassroom.cs
index 949b0fa..110e284 100644
--- a/JianGongYun/TRTC/LiveClassroom.cs
+++ b/JianGongYun/TRTC/LiveClassroom.cs
@@ -21,6 +21,9 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using AduSkin.Controls.Metro;
using System.Configuration;
+using Websocket.Client;
+using System.Windows.Threading;
+using Newtonsoft.Json.Linq;
namespace JianGongYun.TRTC
{
@@ -37,6 +40,7 @@ namespace JianGongYun.TRTC
static string SDKAppKEY { get { return ConfigurationManager.AppSettings[nameof(SDKAppKEY)]; } }
static uint LIVEAppID { get { return uint.Parse(ConfigurationManager.AppSettings[nameof(LIVEAppID)]); } }
static uint LIVEBizid { get { return uint.Parse(ConfigurationManager.AppSettings[nameof(LIVEBizid)]); } }
+ static string WSUrl { get { return ConfigurationManager.AppSettings[nameof(WSUrl)]; } }
///
/// TRTC实例
@@ -53,10 +57,18 @@ namespace JianGongYun.TRTC
///
/// 直播窗口
///
- public static Window CurrentLiveWindow;
+ public static LiveWindow CurrentLiveWindow;
private static LiveWindowViewModel liveWinMode;
public static ClassroomEntity CurrentClassroomEntity { get; private set; }
public static TRTCCloudCallback TRTCCloudCallback = new TRTCCloudCallback();
+
+ ///
+ /// ws客户端
+ ///
+ public static WebsocketClient WSClient = null;
+ public static DispatcherTimer Heartbeat = null;
+ public static string ClassId = null;//章节id
+
///
/// 摄像头帧
///
@@ -121,6 +133,30 @@ namespace JianGongYun.TRTC
_RecoderDir = $"{classroomEntity.ClassHead}_{classroomEntity.ClassSubHead}";
+ //连接WS
+ if (WSClient != null && WSClient.IsRunning)//只连一个
+ {
+ WSClient.Stop(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "connect repeat");
+ WSClient.Dispose();
+ }
+
+ var url = new Uri(WSUrl);
+ WSClient = new WebsocketClient(url);
+ WSClient.ReconnectTimeout = TimeSpan.FromSeconds(30);
+ WSClient.ReconnectionHappened.Subscribe(info =>
+ Console.WriteLine($"Reconnection happened, type: {info.Type}"));
+
+ WSClient.MessageReceived.Subscribe(CurrentLiveWindow.OnMsg);
+ WSClient.Start();
+ ClassId = CurrentClassroomEntity.TeacherId.Split('_')[1];
+ WSClient.Send($"{{code:10000,nick:\"{CurrentClassroomEntity.TeacherName}\",\"room\":\"push_{ClassId}\"}}");//进房间
+
+ //发送心跳包
+ Heartbeat = new DispatcherTimer(DispatcherPriority.Render);
+ Heartbeat.Interval = TimeSpan.FromSeconds(5);
+ Heartbeat.Tick += new EventHandler((a, b) => WSClient.Send("{code:10016}"));
+ Heartbeat.Start();
+
callerWindow?.Hide();//隐藏调用窗口
CurrentLiveWindow.Show();
}
@@ -744,6 +780,11 @@ namespace JianGongYun.TRTC
CurrentLiveWindow = null;
CurrentClassroomEntity = null;
+ Heartbeat.Stop();
+ WSClient.Stop(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "end");
+ WSClient.Dispose();
+ WSClient = null;
+ Heartbeat = null;
lTXDeviceManager.Dispose();
lTXDeviceManager = null;
diff --git a/JianGongYun/TRTC/Models/ChatEntity.cs b/JianGongYun/TRTC/Models/ChatEntity.cs
new file mode 100644
index 0000000..60c6fc7
--- /dev/null
+++ b/JianGongYun/TRTC/Models/ChatEntity.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JianGongYun.TRTC.Models
+{
+ public class ChatEntity
+ {
+ public string Body { get; set; }
+ public string Nick { get; set; }
+ public string Date { get; set; }
+ }
+}
diff --git a/JianGongYun/TRTC/Models/ClassroomEntity.cs b/JianGongYun/TRTC/Models/ClassroomEntity.cs
index 7b2b44d..44d7730 100644
--- a/JianGongYun/TRTC/Models/ClassroomEntity.cs
+++ b/JianGongYun/TRTC/Models/ClassroomEntity.cs
@@ -25,6 +25,10 @@ namespace JianGongYun.TRTC.Models
/// 章节名称
///
public string ClassSubHead { get; set; }
+ ///
+ /// 结束时间
+ ///
+ public DateTime? EndTime { get; set; }
}
}
diff --git a/JianGongYun/TRTC/Utils/ChatItemBgConverter.cs b/JianGongYun/TRTC/Utils/ChatItemBgConverter.cs
new file mode 100644
index 0000000..70d680d
--- /dev/null
+++ b/JianGongYun/TRTC/Utils/ChatItemBgConverter.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace JianGongYun.TRTC
+{
+ public class ChatItemBgConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value == null ? new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)) : parameter;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+}
diff --git a/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs b/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs
index 1af180a..4808041 100644
--- a/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs
+++ b/JianGongYun/TRTC/ViewModels/LiveWindowViewModel.cs
@@ -28,7 +28,7 @@ namespace JianGongYun.TRTC.ViewModels
///
/// 学生总数
///
- private int _StudentCount = 1;
+ private int _StudentCount = 0;
public int StudentCount
{
set
@@ -356,15 +356,15 @@ namespace JianGongYun.TRTC.ViewModels
///
/// 消息集合
///
- private ObservableCollection _Chats = new ObservableCollection() { "1", "2" };
- public ObservableCollection Chats
+ private ObservableCollection _Chats = new ObservableCollection();
+ public ObservableCollection Chats
{
set
{
_Chats = value;
if (PropertyChanged != null)
{
- PropertyChanged(this, new PropertyChangedEventArgs("Chats"));//对StudentCount进行监听
+ PropertyChanged(this, new PropertyChangedEventArgs("Chats"));
}
}
get
diff --git a/JianGongYun/TRTC/Windows/LiveWindow.xaml b/JianGongYun/TRTC/Windows/LiveWindow.xaml
index 6aaa5a9..0ce8c15 100644
--- a/JianGongYun/TRTC/Windows/LiveWindow.xaml
+++ b/JianGongYun/TRTC/Windows/LiveWindow.xaml
@@ -62,7 +62,7 @@
-
+
直播中
@@ -70,7 +70,63 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -205,6 +261,7 @@
请选择要分享的屏幕或前台窗口(上课期间可随时切换)
+
diff --git a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
index 1e276ee..2bb6637 100644
--- a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
+++ b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
@@ -16,6 +16,9 @@ using System.Windows.Threading;
using JianGongYun.TRTC.Components;
using System.Runtime.InteropServices;
using System.ComponentModel;
+using Websocket.Client;
+using Newtonsoft.Json.Linq;
+using System.Diagnostics;
namespace JianGongYun.TRTC.Windows
{
@@ -34,15 +37,80 @@ namespace JianGongYun.TRTC.Windows
InitializeComponent();
this.Icon = new BitmapImage(new Uri("logo.ico", UriKind.RelativeOrAbsolute));
NoticeManager.Initialize();
- //AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出
+ AttachConsole(-1);//把进程挂在控制台,通过命令行启动程序可以看到控制台输出
LiveWindowViewModel = new ViewModels.LiveWindowViewModel();
SettingWindowViewModel = ViewModels.SettingWindowViewModel.GetInstance();
this.DataContext = LiveWindowViewModel;
BorderBrush = new SolidColorBrush(color: Color.FromRgb(42, 43, 48));//窗口标题背景颜色
+
+ for (int i = 0; i < 12; i++)
+ {
+ LiveWindowViewModel.Chats.Add(new Models.ChatEntity());//放几个空聊天数据占位置
+ }
+ Loaded += LiveWindowRightBottomBlock_Loaded1;
+ }
+ private void LiveWindowRightBottomBlock_Loaded1(object sender, RoutedEventArgs e)
+ {
+ if (ChatList.Items.Count > 0)
+ {
+ ChatList.ScrollIntoView(ChatList.Items[ChatList.Items.Count - 1]);
+ }
}
-
-
+ ///
+ /// ws消息
+ ///
+ ///
+ public void OnMsg(ResponseMessage msg)
+ {
+ Debug.Print(msg.Text);
+ Console.WriteLine($"Message received: {msg}");
+ if (msg.MessageType == System.Net.WebSockets.WebSocketMessageType.Text)
+ {
+ var data = JObject.Parse(msg.Text);
+ var temp = data.SelectToken("extend.code");
+ if (temp != null)
+ {
+ var code = temp.ToObject();
+ switch (code)
+ {
+ case 20001:
+ var count = data.SelectToken("extend.mess").ToObject();
+ LiveWindowViewModel.StudentCount = count;
+ break;
+ case 30004://心跳包返回的时间
+ if (DateTime.TryParse(data.SelectToken("extend.date").ToObject(), out var date))
+ {
+ if (date > LiveClassroom.CurrentClassroomEntity.EndTime)//结束时间关闭直播
+ {
+ this.Dispatcher.Invoke(new Action(() =>
+ {
+ AduMessageBox.ShowOK("已到结束时间", "提醒", "确定");
+ StartLive_Click(stoplive, null);
+ }));
+ }
+ }
+ break;
+ }
+ return;
+ }
+ temp = data.SelectToken("body");
+ if (temp != null)//发送消息后服务器的返回
+ {
+ var body = data["body"].ToString();
+ var nick = data["extend"]["nick"].ToString();
+ var time = data["extend"]["time"].ToString();
+ this.Dispatcher.Invoke(new Action(() =>
+ {
+ if (LiveWindowViewModel.Chats.Count > 520)
+ {
+ LiveWindowViewModel.Chats.RemoveAt(0);
+ }
+ LiveWindowViewModel.Chats.Add(new Models.ChatEntity { Body = body, Nick = nick, Date = time });
+ }));
+ }
+ }
+ }
protected override void OnActivated(EventArgs e)
{
@@ -362,5 +430,40 @@ namespace JianGongYun.TRTC.Windows
this.Hide();
blockTop.Show();
}
+
+ public void SendMsg(TextBox text)
+ {
+ if (!string.IsNullOrEmpty(text.Text))
+ {
+ //LiveWindow.LiveWindowViewModel.Chats.Add(new Models.ChatEntity { Body = text.Text });//往Chats集合添加数据会自动更新到界面上
+ LiveClassroom.WSClient.Send($"{{\"code\":10086,\"mess\":\"{text.Text}\",\"room\":\"push_{LiveClassroom.ClassId}\"}}");
+ text.Text = "";
+ }
+ }
+
+ private void Button_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ //输入框回车
+ if (e.Key == Key.Enter)
+ {
+ SendMsg(ChatIpt);
+ }
+ }
+
+ private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+
+ //输入框回车
+ if (e.Key == Key.Enter)
+ {
+ var text = (TextBox)sender;
+ SendMsg(text);
+ }
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ SendMsg(ChatIpt);
+ }
}
}
diff --git a/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml b/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml
index 7d7ba8c..519bfe6 100644
--- a/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml
+++ b/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml
@@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:JianGongYun.TRTC.Windows"
+ xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
ResizeMode="NoResize"
ShowInTaskbar="False"
@@ -12,22 +13,26 @@
AllowsTransparency="True"
Background="Transparent"
MouseDown="Window_MouseDown"
+ xmlns:live="clr-namespace:JianGongYun.TRTC"
Title="" Height="600" Width="200">
+ 9
+
+ 35
+ 5
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
@@ -62,14 +72,53 @@
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml.cs b/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml.cs
index c7f8ab2..661f8e4 100644
--- a/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml.cs
+++ b/JianGongYun/TRTC/Windows/LiveWindowRightBottomBlock.xaml.cs
@@ -15,6 +15,21 @@ using System.Windows.Shapes;
namespace JianGongYun.TRTC.Windows
{
+ public class ScrollingListBox : ListBox
+ {
+ protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ if (e.NewItems == null) return;
+ var newItemCount = e.NewItems.Count;
+
+ if (newItemCount > 0)
+ this.ScrollIntoView(e.NewItems[newItemCount - 1]);
+
+ base.OnItemsChanged(e);
+ }
+ }
+
+
///
/// LiveWindowRightBottomBlock.xaml 的交互逻辑
///
@@ -40,6 +55,16 @@ namespace JianGongYun.TRTC.Windows
this.Top += 100;
Loaded += LiveWindowRightBottomBlock_Loaded;
}
+
+ Loaded += LiveWindowRightBottomBlock_Loaded1;
+ }
+
+ private void LiveWindowRightBottomBlock_Loaded1(object sender, RoutedEventArgs e)
+ {
+ if (ChatList.Items.Count > 0)
+ {
+ ChatList.ScrollIntoView(ChatList.Items[ChatList.Items.Count - 1]);
+ }
}
private void LiveWindowRightBottomBlock_Loaded(object sender, RoutedEventArgs e)
@@ -56,6 +81,7 @@ namespace JianGongYun.TRTC.Windows
PreVideoWrap.Children.Add(view);
view.SetPause(false);
}
+
}
protected override void OnClosing(CancelEventArgs e)
@@ -90,10 +116,9 @@ namespace JianGongYun.TRTC.Windows
if (e.Key == Key.Enter)
{
var text = (TextBox)sender;
- //socket.send(text.Text);
- LiveWindow.LiveWindowViewModel.Chats.Add(text.Text);//往Chats集合添加数据会自动更新到界面上
- text.Text = "";
+ LiveWindow.SendMsg(text);
}
}
+
}
}
diff --git a/JianGongYun/Views/Login.xaml.cs b/JianGongYun/Views/Login.xaml.cs
index 82b001a..bed0d21 100644
--- a/JianGongYun/Views/Login.xaml.cs
+++ b/JianGongYun/Views/Login.xaml.cs
@@ -27,11 +27,12 @@ namespace JianGongYun.Views
const string CLASS_SUB_HEAD = "--classsubhead";
const string TEACHER_ID = "--teacherid";
const string TEACHER_NAME = "--teachername";
+ const string END_TIME = "endtime";
public Login()
{
InitializeComponent();
this.Icon = new BitmapImage(new Uri("logo.ico", UriKind.Relative));
- string errMsg = "", classHead = default, classSubHead = default, teacherId = default, teacherName = default;
+ string errMsg = "", classHead = default, classSubHead = default, teacherId = default, teacherName = default, endtime = default;
var urltemps = Environment.GetCommandLineArgs();
if (urltemps.Length < 2)
{
@@ -44,7 +45,7 @@ namespace JianGongYun.Views
errMsg = "Startup Parameter Error";
goto Skip;
}
- var args= HttpUtility.UrlDecode(first, Encoding.UTF8).Replace("://","|").Split("|");
+ var args = HttpUtility.UrlDecode(first, Encoding.UTF8).Replace("://", "|").Split("|");
int indexTemp = Array.IndexOf(args, CLASS_HEAD);
if (indexTemp < 0)
{
@@ -77,7 +78,15 @@ namespace JianGongYun.Views
}
teacherName = args[indexTemp + 1];
- Skip:
+ indexTemp = Array.IndexOf(args, END_TIME);
+ if (indexTemp < 0)
+ {
+ errMsg = $"{nameof(END_TIME)} NULL";
+ goto Skip;
+ }
+ endtime = args[indexTemp + 1];
+
+ Skip:
if (!string.IsNullOrWhiteSpace(errMsg))
{
MessageBox.Show(errMsg, "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
@@ -90,7 +99,8 @@ namespace JianGongYun.Views
ClassHead = classHead,
ClassSubHead = classSubHead,
TeacherId = teacherId,
- TeacherName = teacherName
+ TeacherName = teacherName,
+ EndTime = string.IsNullOrEmpty(endtime) ? null : new DateTime?(DateTime.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(endtime))))
});
}
}
diff --git a/WSDemo/Program.cs b/WSDemo/Program.cs
new file mode 100644
index 0000000..827db0b
--- /dev/null
+++ b/WSDemo/Program.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Websocket.Client;
+
+namespace WSDemo
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var exitEvent = new ManualResetEvent(false);
+ var url = new Uri("wss://web.cqjgjyw.cn/websocket");
+
+ using (var client = new WebsocketClient(url))
+ {
+ client.ReconnectTimeout = TimeSpan.FromSeconds(30);
+ client.ReconnectionHappened.Subscribe(info =>
+ Console.WriteLine($"Reconnection happened, type: {info.Type}"));
+
+ client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
+ client.StartOrFail();
+
+ Task.Run(() => client.Send("{code:10000,nick:\"张三\",\"room\":\"push_5678\"}"));
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ client.Send($"{{\"code\":10086,\"mess\":\"{Guid.NewGuid()}\",\"room\":\"push_5678\"}}");
+ client.Send("{code:10016}");
+ Thread.Sleep(5000);
+ }
+ });
+
+ exitEvent.WaitOne();
+ }
+ }
+ }
+}
diff --git a/WSDemo/WSDemo.csproj b/WSDemo/WSDemo.csproj
new file mode 100644
index 0000000..f5e75b9
--- /dev/null
+++ b/WSDemo/WSDemo.csproj
@@ -0,0 +1,13 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+