天天看點

Silverlight與WCF之間的通信(6)silverlight+wcf+tcp視訊通信[1]單工模式

其實嚴格來講,這個實作并非真正意義上的視訊通信,既不是P2P的,也沒有很高的性能,因為基本上是兩個用戶端同時往伺服器上傳遞視訊資訊,然後由伺服器進行中轉到對方。

重點在于兩點

IIS根目錄下放clientaccesspolicy.xml檔案

注意服務中定義資料量大小2147483646,否則有可能傳遞不了

這邊是單向的用戶端定時向伺服器傳遞帶聊天辨別的資料流: 

代碼

[DataContract] 

    public class UserVideo 

    { 

        [DataMember] 

        public string UserName { get; set; } 

        public string PartnerName { set; get; } 

        public byte[] VideoByte { set; get; } 

    }  

服務契約隻有兩個,一個是用來存儲視訊流,一個是用來提供視訊流的 

[ServiceContract] 

    public interface IChatService 

        [OperationContract] 

        void SendVideo(UserVideo userVideo); 

        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通信。

     本文轉自wengyuli 51CTO部落格,原文連結:http://blog.51cto.com/wengyuli/587192,如需轉載請自行聯系原作者