This commit is contained in:
parent
ba5f72c73e
commit
2d3c116a32
|
@ -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
|
||||
|
|
|
@ -6,5 +6,6 @@
|
|||
<add key="LIVEAppID" value="1302772646"/>
|
||||
<add key="LIVEBizid" value="110962"/>
|
||||
<add key="RoomId" value ="654657754"/>
|
||||
<add key="WSUrl" value ="wss://web.cqjgjyw.cn/websocket"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.5.1.20201229" />
|
||||
<PackageReference Include="OpenCvSharp4.WpfExtensions" Version="4.5.1.20201229" />
|
||||
<PackageReference Include="Websocket.Client" Version="4.3.30" />
|
||||
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'net45'">
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Margin" Value="0,1,1,6"/>
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Width" Value="5"/>
|
||||
<Setter Property="MinWidth" Value="5"/>
|
||||
<Setter Property="Opacity" Value="0.2"/>
|
||||
<Setter Property="Template">
|
||||
|
|
|
@ -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)]; } }
|
||||
|
||||
/// <summary>
|
||||
/// TRTC实例
|
||||
|
@ -53,10 +57,18 @@ namespace JianGongYun.TRTC
|
|||
/// <summary>
|
||||
/// 直播窗口
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
/// <summary>
|
||||
/// ws客户端
|
||||
/// </summary>
|
||||
public static WebsocketClient WSClient = null;
|
||||
public static DispatcherTimer Heartbeat = null;
|
||||
public static string ClassId = null;//章节id
|
||||
|
||||
/// <summary>
|
||||
/// 摄像头帧
|
||||
/// </summary>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -25,6 +25,10 @@ namespace JianGongYun.TRTC.Models
|
|||
/// 章节名称
|
||||
/// </summary>
|
||||
public string ClassSubHead { get; set; }
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ namespace JianGongYun.TRTC.ViewModels
|
|||
/// <summary>
|
||||
/// 学生总数
|
||||
/// </summary>
|
||||
private int _StudentCount = 1;
|
||||
private int _StudentCount = 0;
|
||||
public int StudentCount
|
||||
{
|
||||
set
|
||||
|
@ -356,15 +356,15 @@ namespace JianGongYun.TRTC.ViewModels
|
|||
/// <summary>
|
||||
/// 消息集合
|
||||
/// </summary>
|
||||
private ObservableCollection<string> _Chats = new ObservableCollection<string>() { "1", "2" };
|
||||
public ObservableCollection<string> Chats
|
||||
private ObservableCollection<ChatEntity> _Chats = new ObservableCollection<ChatEntity>();
|
||||
public ObservableCollection<ChatEntity> Chats
|
||||
{
|
||||
set
|
||||
{
|
||||
_Chats = value;
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs("Chats"));//对StudentCount进行监听
|
||||
PropertyChanged(this, new PropertyChangedEventArgs("Chats"));
|
||||
}
|
||||
}
|
||||
get
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
<TextBlock FontSize="14" Padding="3 0 0 0" Foreground="#bbbbbb" Text="人"></TextBlock>
|
||||
</StackPanel>
|
||||
<Metro:AduFlatButton Content="开始直播" Click="StartLive_Click" Tag="True" Canvas.Bottom="13" Canvas.Right="25" Visibility="{Binding IsLive, Converter={StaticResource UnVisibilityOfBool}}"></Metro:AduFlatButton>
|
||||
<Metro:AduFlatButton Content="结束直播" Click="StartLive_Click" Tag="False" Type="error" Canvas.Bottom="13" Canvas.Right="25" Visibility="{Binding IsLive, Converter={StaticResource VisibilityOfBool}}"></Metro:AduFlatButton>
|
||||
<Metro:AduFlatButton Content="结束直播" x:Name="stoplive" Click="StartLive_Click" Tag="False" Type="error" Canvas.Bottom="13" Canvas.Right="25" Visibility="{Binding IsLive, Converter={StaticResource VisibilityOfBool}}"></Metro:AduFlatButton>
|
||||
<StackPanel Visibility="{Binding IsLive, Converter={StaticResource VisibilityOfBool}}" Orientation="Horizontal" Canvas.Bottom="20" Canvas.Right="150">
|
||||
<Ellipse VerticalAlignment="Center" Width="10" Fill="#00cc66" Height="10"></Ellipse>
|
||||
<TextBlock FontSize="15" Foreground="White" Margin="7 0 0 0">直播中</TextBlock>
|
||||
|
@ -70,7 +70,63 @@
|
|||
</StackPanel>
|
||||
</Canvas>
|
||||
<!--右方聊天学员面板-->
|
||||
<Canvas DockPanel.Dock="Right" Width="280" Background="#2f3035">
|
||||
<Canvas x:Name="ChatWrap" DockPanel.Dock="Right" Width="280" Background="#2f3035">
|
||||
<DockPanel Height="{Binding ElementName=ChatWrap,Path=ActualHeight}" Width="{Binding ElementName=ChatWrap,Path=ActualWidth}">
|
||||
<DockPanel Height="60" DockPanel.Dock="Bottom">
|
||||
<Button PreviewKeyDown="Button_PreviewKeyDown" Click="Button_Click" Foreground="White" Background="#3e7fff" Margin="0 12 12 12" Width="70" DockPanel.Dock="Right">发 送</Button>
|
||||
<TextBox x:Name="ChatIpt" PreviewKeyDown="TextBox_PreviewKeyDown" VerticalContentAlignment="Center" Padding="12 0" Foreground="White" Background="Transparent" Margin="12 12 0 12"></TextBox>
|
||||
</DockPanel>
|
||||
<Border BorderBrush="#888" BorderThickness="0 0 0 1">
|
||||
<Grid>
|
||||
<local:ScrollingListBox x:Name="ChatList" BorderThickness="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Chats}" Background="Transparent">
|
||||
<ListBox.Resources>
|
||||
<Style TargetType="ScrollViewer" BasedOn="{StaticResource CusScroll}"></Style>
|
||||
<Style TargetType="local:ScrollingListBox">
|
||||
<Setter Property="ItemContainerStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Border x:Name="Border" BorderThickness="0">
|
||||
<Label x:Name="Label" VerticalAlignment="Center" Padding="12" HorizontalAlignment="Left" FontSize="13px">
|
||||
<ContentPresenter></ContentPresenter>
|
||||
</Label>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="#efefef"></Setter>
|
||||
<!--<Setter TargetName="Border" Property="Background" Value="{StaticResource itembg}"></Setter>-->
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ListBox.Resources>
|
||||
<ListBox.ItemTemplate>
|
||||
<!--自定义ListBox项样式-->
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Foreground="#3c77eb" TextWrapping="Wrap" Text="{Binding Path=Nick}">
|
||||
</TextBlock>
|
||||
<TextBlock Margin="6 0 0 0" Foreground="#888888" TextWrapping="Wrap" Text="{Binding Path=Date}">
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<TextBlock Margin="0 6 0 0" Foreground="White" TextWrapping="Wrap" Text="{Binding Path=Body}">
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</local:ScrollingListBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DockPanel>
|
||||
</Canvas>
|
||||
<!--下方教程面板-->
|
||||
<Canvas DockPanel.Dock="Bottom" Height="30" Background="#2a2b30">
|
||||
|
@ -205,6 +261,7 @@
|
|||
<TextBlock Foreground="White" FontSize="20" FontWeight="Bold" Padding="10" HorizontalAlignment="Center" VerticalAlignment="Center">请选择要分享的屏幕或前台窗口(上课期间可随时切换)</TextBlock>
|
||||
</StackPanel>
|
||||
<!--列表视图-->
|
||||
<!--Style="{StaticResource CusScroll}"-->
|
||||
<ScrollViewer Style="{StaticResource CusScroll}" Canvas.Right="0" Canvas.Top="50" Height="480" Width="{Binding ElementName=ScrollWrap,Path=ActualWidth}">
|
||||
<ListBox MouseUp="ShareList_Selected" SelectedValuePath="Info" SelectedValue="{Binding CurrentShareScreen}" ItemsSource="{Binding LiveScreens}" Template="{StaticResource ShareListTemplate}" ItemTemplate="{StaticResource ShareListItemTemplate}"></ListBox>
|
||||
</ScrollViewer>
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ws消息
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
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<int>();
|
||||
switch (code)
|
||||
{
|
||||
case 20001:
|
||||
var count = data.SelectToken("extend.mess").ToObject<int>();
|
||||
LiveWindowViewModel.StudentCount = count;
|
||||
break;
|
||||
case 30004://心跳包返回的时间
|
||||
if (DateTime.TryParse(data.SelectToken("extend.date").ToObject<string>(), 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
<Window.Resources>
|
||||
<System:Double x:Key="rd">9</System:Double>
|
||||
<SolidColorBrush x:Key="itembg" Color="#50000000" />
|
||||
<System:Double x:Key="ipth">35</System:Double>
|
||||
<System:Double x:Key="far">5</System:Double>
|
||||
|
||||
<CornerRadius x:Key="fullrd" TopLeft="{StaticResource rd}" TopRight="{StaticResource rd}" BottomRight="{StaticResource rd}" BottomLeft="{StaticResource rd}"></CornerRadius>
|
||||
<CornerRadius x:Key="arird" TopLeft="{StaticResource rd}" TopRight="{StaticResource rd}" BottomRight="{StaticResource rd}" BottomLeft="0"></CornerRadius>
|
||||
<Thickness x:Key="fullfar" Left="{StaticResource far}" Top="{StaticResource far}" Bottom="{StaticResource far}" Right="{StaticResource far}"></Thickness>
|
||||
<Thickness x:Key="hfar" Left="{StaticResource far}" Right="{StaticResource far}"></Thickness>
|
||||
|
||||
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Grid>
|
||||
<TextBox Padding="14,0,14,0" VerticalContentAlignment="Center" Text="{Binding Path=Text,
|
||||
RelativeSource={RelativeSource TemplatedParent},
|
||||
Mode=TwoWay,
|
||||
UpdateSourceTrigger=PropertyChanged}"
|
||||
x:Name="textSource"
|
||||
Background="Transparent"
|
||||
Foreground="White"
|
||||
Panel.ZIndex="2" />
|
||||
<TextBox Padding="14,0,14,0" VerticalContentAlignment="Center" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
|
||||
<TextBox Margin="0" Padding="{StaticResource hfar}" BorderThickness="0" VerticalContentAlignment="Center" Text="{Binding Path=Text,RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="textSource" Background="Transparent" Foreground="White" Panel.ZIndex="2" />
|
||||
<TextBox Margin="0" Padding="{StaticResource hfar}" BorderThickness="0" VerticalContentAlignment="Center" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
|
||||
<TextBox.Style>
|
||||
<Style TargetType="{x:Type TextBox}">
|
||||
<Setter Property="Foreground" Value="Transparent"/>
|
||||
|
@ -38,17 +43,22 @@
|
|||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBox.Style>
|
||||
<TextBox.Resources>
|
||||
<Style TargetType="{x:Type Border}">
|
||||
<Setter Property="CornerRadius" Value="{StaticResource fullrd}"/>
|
||||
<Setter Property="BorderBrush" Value="#c1d0dc"/>
|
||||
</Style>
|
||||
</TextBox.Resources>
|
||||
</TextBox>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="VisibilityOfBool" />
|
||||
<!--自定义ListBox项样式-->
|
||||
<DataTemplate x:Key="cusItem">
|
||||
<TextBlock Foreground="White" Text="{Binding}"></TextBlock>
|
||||
</DataTemplate>
|
||||
<live:ChatItemBgConverter x:Key="BgByVal" />
|
||||
|
||||
</Window.Resources>
|
||||
<DockPanel>
|
||||
<!--预览框-->
|
||||
|
@ -62,14 +72,53 @@
|
|||
</Canvas>
|
||||
</Grid>
|
||||
<!--聊天版面-->
|
||||
<Grid Background="#33000000">
|
||||
<Grid Background="#01000000">
|
||||
<DockPanel>
|
||||
<!--输入框-->
|
||||
<DockPanel DockPanel.Dock="Bottom" Height="30">
|
||||
<TextBox Background="Transparent" Foreground="White" Style="{StaticResource placeHolder}" PreviewKeyDown="TextBox_PreviewKeyDown" Tag="输入"></TextBox>
|
||||
<DockPanel Margin="{StaticResource fullfar}" DockPanel.Dock="Bottom" Height="{StaticResource ipth}">
|
||||
<TextBox Background="{StaticResource itembg}" Height="{StaticResource ipth}" Padding="{StaticResource fullfar}" Foreground="White" Style="{StaticResource placeHolder}" PreviewKeyDown="TextBox_PreviewKeyDown" Tag="输入"></TextBox>
|
||||
</DockPanel>
|
||||
<!--消息列表-->
|
||||
<ListBox ItemTemplate="{StaticResource cusItem}" ItemsSource="{Binding Chats}" Background="Transparent"></ListBox>
|
||||
<local:ScrollingListBox x:Name="ChatList" BorderThickness="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Chats}" Background="Transparent">
|
||||
<ListBox.Resources>
|
||||
<Style TargetType="ScrollViewer" BasedOn="{StaticResource CusScroll}"></Style>
|
||||
<Style TargetType="local:ScrollingListBox">
|
||||
<Setter Property="ItemContainerStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Border x:Name="Border" Padding="{StaticResource fullfar}" Margin="{StaticResource fullfar}" BorderThickness="0" Background="{Binding Path=Body,Converter={StaticResource BgByVal},ConverterParameter={StaticResource itembg}}" CornerRadius="{StaticResource arird}">
|
||||
<Label x:Name="Label" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="12px">
|
||||
<ContentPresenter></ContentPresenter>
|
||||
</Label>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="#efefef"></Setter>
|
||||
<Setter TargetName="Border" Property="Background" Value="{StaticResource itembg}"></Setter>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ListBox.Resources>
|
||||
<ListBox.ItemTemplate>
|
||||
<!--自定义ListBox项样式-->
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="White" TextWrapping="Wrap" Text="{Binding Path=Body}">
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</local:ScrollingListBox>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// LiveWindowRightBottomBlock.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Websocket.Client" Version="4.3.30" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Loading…
Reference in New Issue