你的分享就是我们的动力 ---﹥

Silverlight与WCF之间的通信(6)silverlight+wcf+tcp视频通信[1]

时间:2011-09-30 10:05来源:www.chengxuyuans.com 点击:

其实严格来讲,这个实现并非真正意义上的视频通信,既不是P2P的,也没有很高的性能,因为基本上 是两个客户端同时往服务器上传递视频信息,然后由服务器进行中转到对方。

重点在于两点

IIS根目录下放clientaccesspolicy.xml文件

注意服务中定义数据量大小2147483646,否则有可能传递不了

这边是单向的客户端定时向服务器传递带聊天标识的数据流

[DataContract]
    public class UserVideo
    {
        [DataMember]
        public string UserName { get; set; }
        [DataMember]
        public string PartnerName { set; get; }
        [DataMember]
        public byte[] VideoByte { set; get; }
    }

服务契约只有两个,一个是用来存储视频流,一个是用来提供视频流的

[ServiceContract]
    public interface IChatService
    {
        [OperationContract]
        void SendVideo(UserVideo userVideo);
        [OperationContract]
        List<UserVideo> GetVideos(string userName,string partnerName);
    }

实现也很简单就是往一个静态的List中添加对象

public class ChatService : 

IChatService
    {
        private static List<UserVideo> listVideos = new List<UserVideo>();
        public void SendVideo(UserVideo userVideo)
        {
            listVideos.Add(userVideo);
        }
        public List<UserVideo> GetVideos(string userName,string partnerName)
        {
            var list = listVideos.Where(m => m.UserName == userName && 

m.PartnerName == partnerName).ToList();
            listVideos.RemoveAll(m => m.PartnerName == partnerName && m.UserName 

== userName);
            return list;
        }
    }

接下来是host方法

public class MyHost
    {
        static ServiceHost host = null;
        public static void Open()
        {
            host = new ServiceHost(typeof(ChatService));
            host.Open();
        }
        public static void Close()
        {
            if (host != null && host.State == CommunicationState.Opened)
            {
                host.Close();
            }
            host = null;
        }
    }

最后是启动服务进行监听

public class Program
    {
        static void Main(string[] args)
        {
            MyHost.Open();
            System.Console.WriteLine("服务已经启动...   敲任意键停止服务");
            System.Console.ReadLine();
            MyHost.Close();
        }
    }

客户端方法:

开始视频播放

this.btnStartVideo.Click += (o, ev) =>
            {
                if (source != null)
                {
                    source.Stop();
                    source.VideoCaptureDevice = 

CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
                    VideoBrush vBrush = new VideoBrush();
                    vBrush.SetSource(source);
                    this.rectangleUser.Fill = vBrush;
                    if (CaptureDeviceConfiguration.AllowedDeviceAccess || 

CaptureDeviceConfiguration.RequestDeviceAccess())
                    {
                        source.Start();
                    }
                }
            };

向服务器发送数据流

this.btnSendVideo.Click += (o, ev) =>
            {
                timerForSend = new System.Windows.Threading.DispatcherTimer();
                timerForSend.Interval = new TimeSpan(0, 0, 0, 0, 150);
                timerForSend.Tick += (o1, e1) => {
                    proxy = new ChatServiceClient();
                    WriteableBitmap bmp = new WriteableBitmap(this.rectangleUser, null);
                    MemoryStream ms = new MemoryStream();
                    EncodeJpeg(bmp, ms);
                    UserVideo userVideo = new UserVideo();
                    userVideo.PartnerName = this.Partner;
                    userVideo.UserName = this.User;
                    userVideo.VideoByte = ms.GetBuffer();
                    proxy.SendVideoCompleted += (o2, e2) => { };
                    proxy.SendVideoAsync(userVideo);
                };
                timerForSend.Start();
            };

从服务期上取得数据流

void ReceiveVideo()
        {
            timerForReceive = new System.Windows.Threading.DispatcherTimer();
            timerForReceive.Interval = new TimeSpan(0, 0, 0, 0, 100);
            timerForReceive.Tick += (o, e) => {
                proxy = new ChatServiceClient();
                proxy.GetVideosCompleted += (se, ev) =>
                {
                    if (ev.Error == null)
                    {
                        foreach (ChatService.UserVideo video in ev.Result)
                        {
                            this.imagePartner.Dispatcher.BeginInvoke(() => {
                                MemoryStream ms = new MemoryStream(video.VideoByte);
                                BitmapImage bitmap = new BitmapImage();
                                bitmap.SetSource(ms);
                                imagePartner.Source = bitmap;
                                ms.Close();
                            });
                        }
                    }
                };
                proxy.GetVideosAsync(User, Partner);
            };
            timerForReceive.Start();
        }

单工模式的缺点显而易见,请求--》答复比较耗时,我们下一步将会改造成双工模式的tcp通信。

转载注明地址:http://www.chengxuyuans.com/slverlight/19413.html