Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)...
生活随笔
收集整理的這篇文章主要介紹了
Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言:
近期在忙點“秋色園”的事情,所以網絡象棋這一塊文章就寫的相對慢,而且剛好接上篇:Silverlight+WCF 實戰-網絡象棋最終篇之非線程阻塞倒計時窗口(四)??之后,是一些代碼修改,會比較枯燥,所以沒接著寫,不過有昨天有網頁表示對象棋在線演示中的?對戰視頻?感興趣,希望可以提前看到代碼,所以本次就提前寫里面的對戰視頻這一塊。
由于對戰視頻采用控制臺程序,并沒有在服務器運行,所以在線演示版本里一進入顯示是顯示“未鏈接”的提示。 作者:路過秋天?博客:http://cyq1162.cnblogs.com/
?
?一:對戰視頻?簡單原理:
1:由于Silverlight不支持點對點方式傳輸,因此只能通過服務器中轉方式進行。2:視頻的傳輸是圖片字節,因此壓縮圖片是相當必要的。
3:中間的服務選什么?一開始我是在嘗試使用WCF的tcp方式,后來折騰配置文件太痛苦,直接轉使用Socket通訊,一來有性能優勢,二來減少折騰。
?
二:對戰視頻?步驟解析:
1:客戶端打開視頻2:客戶端向遠端Socket注冊[按規則定好的]編號[服務端根據編號查要轉發的對象]
3:服務端接收編號并注冊,收集一系列編號列表。
4:客戶端發送視頻
5:服務端接收視頻,并根據規則查找另一個編號,將視頻字節轉發
6:另一個客戶端接收視頻并顯示
?
三:對戰視頻?具體實施
?
1:如何打開視頻
在Siverlight中打開視頻相當的簡單,都有注釋,就不多解說了代碼如下:
????????private?void?btnStart_Click(object?sender,?RoutedEventArgs?e)????????{
????????????VideoCaptureDevice?device?=?CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();//獲取系統默認視頻設備
????????????if?(device?==?null)
????????????{
????????????????MessageBox.Show("沒有檢測到設備!");
????????????????return;
????????????}
????????????if?(CaptureDeviceConfiguration.RequestDeviceAccess())//請求設備
????????????{
????????????????CaptureSource?source?=?new?CaptureSource()//數據源
????????????????{
????????????????????VideoCaptureDevice?=?device//設置屬性,將數據源綁定到視頻
????????????????};
????????????????VideoBrush?brush?=?new?VideoBrush();//視頻刷子
????????????????brush.SetSource(source);//視頻刷子從視頻源獲取視頻
????????????????source.Start();
????????????????myVideo.Fill?=?brush;//最后填充Rectangle [myVideo只是一個普通Rectangle]
????????????}
????????}
界面Rectangle代碼:
<Canvas?Width="160"?Height="160"?Background="Red"?Margin="22,109,518,531"?Name="canVideo"><Rectangle?Height="160"?Name="myVideo"?Stroke="Black"?StrokeThickness="1"?Width="160"?Canvas.Left="0"?Canvas.Top="0"?/>
</Canvas>
?
運行后我們看下效果,[這里用了本地的虛擬視頻,開了3個瀏覽器并排截了圖,第4張是不一樣的哦],中間提示確認是否打開視頻就不截圖了:
?
2:Silverlight如何使用Socket進行通訊
由于Silverlight一般是不允許跨域通訊,因此,其Socket通訊也要比普通的Socket通訊麻煩一小點,不過這麻煩的小點只表現在服務端。下面進行代碼解析:以下代碼將一步扣一步,具體的連環扣如下:建立鏈接-》注冊編號-》開新線程待接收視頻-》收到視頻處理顯示。
?
2.1:與遠程建立鏈接:
???????Socket?videoSocket;//全局定義一個Socket????????private?void?btnSocketConn_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????if?(videoSocket?==?null)//實例化Socket
????????????{
????????????????videoSocket?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Stream,?ProtocolType.Tcp);
????????????}
????????????SocketAsyncEventArgs?socketEvent=new?SocketAsyncEventArgs()//通訊參數
????????????{
????????????????RemoteEndPoint=new?IPEndPoint(IPAddress.Parse("192.168.0.48"),4505),//設置連接的IP與端口
????????????};
????????????socketEvent.Completed?+=?new?EventHandler<SocketAsyncEventArgs>(socketEvent_Completed);
????????????videoSocket.ConnectAsync(socketEvent);//異步鏈接到遠程
????????}
????????void?socketEvent_Completed(object?sender,?SocketAsyncEventArgs?e)//鏈接完成后
????????{
???????????//這里要寫點什么呢?
????????}
?
2.2:注冊編號[這里的規則是“房間號+棋手顏色值”]
????????void?socketEvent_Completed(object?sender,?SocketAsyncEventArgs?e)????????{
????????????if?(e.SocketError?==?SocketError.Success)
????????????{
????????????????byte[]?buffer?=?System.Text.Encoding.UTF8.GetBytes("11");//我的編號,11=1房間+紅色玩家1,對應的就是12=1房間+黑色玩家2
????????????????SocketAsyncEventArgs?dataEvent?=?new?SocketAsyncEventArgs();
????????????????dataEvent.SetBuffer(buffer,?0,?buffer.Length);
????????????????dataEvent.Completed?+=?new?EventHandler<SocketAsyncEventArgs>(dataEvent_Completed);
????????????????videoSocket.SendAsync(dataEvent);//發送號碼到服務端注冊
????????????}
????????}
????????void?dataEvent_Completed(object?sender,?SocketAsyncEventArgs?e)
????????{??
???????????//號碼發送過去了,接下這里干點什么呢?
????????}
?
2.3:開新線程,等待接收對方視頻
???????void?dataEvent_Completed(object?sender,?SocketAsyncEventArgs?e)????????{
????????????System.Threading.Thread?thread?=?new?System.Threading.Thread(new?System.Threading.ThreadStart(Receive));//開啟線程
????????????thread.Start();
????????}
????????void?Receive()//接收視頻處理
????????{
????????????byte[]?buffer?=?new?byte[1024?*?1024];
????????????while?(true)
????????????{
????????????????SocketAsyncEventArgs?receiveEvent?=?new?SocketAsyncEventArgs();
????????????????receiveEvent.SetBuffer(buffer,?0,?buffer.Length);
????????????????receiveEvent.Completed?+=?new?EventHandler<SocketAsyncEventArgs>(receiveEvent_Completed);
????????????????videoSocket.ReceiveAsync(receiveEvent);
????????????????
????????????????System.Threading.Thread.Sleep(50);//小小休眠一下,不要干活太累
????????????}
????????}
????????void?receiveEvent_Completed(object?sender,?SocketAsyncEventArgs?e)
????????{
????????????//如果收到視頻,我們要怎么處理呢?????????????
????????}
?
2.4:將視頻顯示出來,需要用主線程來操作
????????SynchronizationContext?syn=SynchronizationContext.Current;//獲取當前主線程????????void?receiveEvent_Completed(object?sender,?SocketAsyncEventArgs?e)
????????{
???????????byte[]?data=e.Buffer;
???????????if?(data[0]>0)
???????????{
??????????????syn.Post(SetVideo,?data);//由于新線程無法對控件進行操作,需要主線程來調用
???????????}
????????}?
????????void?SetVideo(object?data)//設置視頻
????????{
????????????MemoryStream?stream=null;
????????????WriteableBitmap?img=null;
????????????try
????????????{
????????????????stream?=?new?MemoryStream(data?as?byte[]);
????????????????img?=?new?WriteableBitmap(160,?160);
????????????????img.SetSource(stream);
????????????????imgVideo.Source?=?img;//直接賦下值,就設置好了。
????????????}
????????????catch
????????????{
????????????????return;
????????????}
????????????finally
????????????{
????????????????if?(stream?!=?null)
????????????????{
????????????????????stream.Close();
????????????????}
????????????????if?(img?!=?null)
????????????????{
????????????????????img?=?null;
????????????????}
????????????}
????????}
上面的imgVideo為:
<Image?Height="160"?HorizontalAlignment="Left"?Margin="207,109,0,0"?Name="imgVideo"?Stretch="Fill"?VerticalAlignment="Top"?Width="160"?/>?
至此,我們連續完成了“打開視頻—》注冊—》等待接收-》接收時開主線程顯示”,我們提前看一下完成后接收時的效果圖:?
?
紅色塊是顯示視頻的區域,當前圖片說明左側沒有開啟視頻,只是開了接收,右側開了視頻,并發送視頻。?
下面再順路看一下開啟的服務端中轉Socket的運行:
?
OK,本節就先到此,下節我們再講“視頻圖片的壓縮與發送”+服務端處理中轉流程
?
最后:謝謝大家對本系列的喜歡,謝謝支持~
PS:傳說點一下推薦會有10個園豆,喜歡麻煩點一下“推薦”,thank you very much!!
轉載于:https://www.cnblogs.com/cyq1162/archive/2010/12/01/1893583.html
總結
以上是生活随笔為你收集整理的Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)...的全部內容,希望文章能夠幫你解決所遇到的問題。