Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)

简介:

前言:

复制代码
近期在忙点“秋色园”的事情,所以网络象棋这一块文章就写的相对慢,而且刚好接上篇:Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)   之后,

是一些代码修改,会比较枯燥,所以没接着写,不过有昨天有网页表示对象棋在线演示中的 对战视频 感兴趣,希望可以提前看到代码,所以本次就提前写里面的对战视频这一块。

由于对战视频采用控制台程序,并没有在服务器运行,所以在线演示版本里一进入显示是显示“未链接”的提示。
复制代码

 

 一:对战视频 简单原理:

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!!

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2010/12/01/1893583.html

相关文章
|
11天前
|
SQL 安全 算法
网络安全的盾牌与剑:漏洞防御与加密技术的实战应用
【9月更文挑战第30天】在数字时代的浪潮中,网络安全成为守护信息资产的关键防线。本文深入浅出地探讨了网络安全中的两大核心议题——安全漏洞与加密技术,并辅以实例和代码演示,旨在提升公众的安全意识和技术防护能力。
|
24天前
|
网络协议 网络虚拟化
接收网络包的过程——从硬件网卡解析到IP
【9月更文挑战第18天】这段内容详细描述了网络包接收过程中机制。当网络包触发中断后,内核处理完这批网络包,会进入主动轮询模式,持续处理后续到来的包,直至处理间隙返回其他任务,从而减少中断次数,提高处理效率。此机制涉及网卡驱动初始化时注册轮询函数,通过软中断触发后续处理,并逐步深入内核网络协议栈,最终到达TCP层。整个接收流程分为多个层次,包括DMA技术存入Ring Buffer、中断通知CPU、软中断处理、以及进入内核网络协议栈等多个步骤。
|
21天前
|
网络协议 Python
告别网络编程迷雾!Python Socket编程基础与实战,让你秒变网络达人!
在网络编程的世界里,Socket编程是连接数据与服务的关键桥梁。对于初学者,这往往是最棘手的部分。本文将用Python带你轻松入门Socket编程,从创建TCP服务器与客户端的基础搭建,到处理并发连接的实战技巧,逐步揭开网络编程的神秘面纱。通过具体的代码示例,我们将掌握Socket的基本概念与操作,让你成为网络编程的高手。无论是简单的数据传输还是复杂的并发处理,Python都能助你一臂之力。希望这篇文章成为你网络编程旅程的良好开端。
39 3
|
22天前
|
机器学习/深度学习 JSON API
HTTP协议实战演练场:Python requests库助你成为网络数据抓取大师
在数据驱动的时代,网络数据抓取对于数据分析、机器学习等至关重要。HTTP协议作为互联网通信的基石,其重要性不言而喻。Python的`requests`库凭借简洁的API和强大的功能,成为网络数据抓取的利器。本文将通过实战演练展示如何使用`requests`库进行数据抓取,包括发送GET/POST请求、处理JSON响应及添加自定义请求头等。首先,请确保已安装`requests`库,可通过`pip install requests`进行安装。接下来,我们将逐一介绍如何利用`requests`库探索网络世界,助你成为数据抓取大师。在实践过程中,务必遵守相关法律法规和网站使用条款,做到技术与道德并重。
32 2
|
29天前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
54 8
|
24天前
|
数据采集 API 开发者
🚀告别网络爬虫小白!urllib与requests联手,Python网络请求实战全攻略
在网络的广阔世界里,Python凭借其简洁的语法和强大的库支持,成为开发网络爬虫的首选语言。本文将通过实战案例,带你探索urllib和requests两大神器的魅力。urllib作为Python内置库,虽API稍显繁琐,但有助于理解HTTP请求本质;requests则简化了请求流程,使开发者更专注于业务逻辑。从基本的网页内容抓取到处理Cookies与Session,我们将逐一剖析,助你从爬虫新手成长为高手。
48 1
|
23天前
|
Python
HTTP协议不再是迷!Python网络请求实战,带你走进网络世界的奥秘
本文介绍了HTTP协议,它是互联网信息传递的核心。作为客户端与服务器通信的基础,HTTP请求包括请求行、头和体三部分。通过Python的`requests`库,我们可以轻松实现HTTP请求。本文将指导你安装`requests`库,并通过实战示例演示如何发送GET和POST请求。无论你是想获取网页内容还是提交表单数据,都能通过简单的代码实现。希望本文能帮助你在Python网络请求的道路上迈出坚实的一步。
36 0
|
1月前
|
SQL 安全 网络安全
网络安全之盾:漏洞防御与加密技术的实战应用
【9月更文挑战第2天】在数字时代的浪潮中,网络安全成为保护个人隐私和企业资产的坚固盾牌。本文深入探讨了网络安全的两个核心要素:防御漏洞和加密技术。我们将从基础概念入手,逐步剖析常见的网络攻击手段,并分享如何通过实践加强安全意识。同时,提供代码示例以增强理解,旨在为读者构建一道坚不可摧的网络安全防线。
|
2月前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
77 0
|
2月前
|
安全 开发者 数据安全/隐私保护
Xamarin 的安全性考虑与最佳实践:从数据加密到网络防护,全面解析构建安全移动应用的六大核心技术要点与实战代码示例
【8月更文挑战第31天】Xamarin 的安全性考虑与最佳实践对于构建安全可靠的跨平台移动应用至关重要。本文探讨了 Xamarin 开发中的关键安全因素,如数据加密、网络通信安全、权限管理等,并提供了 AES 加密算法的代码示例。
40 0