其實嚴格來講,這個實作并非真正意義上的視訊通信,既不是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,如需轉載請自行聯系原作者