Effect
First, let's look at the results. The basic logic is that two people continuously transmit videos to the server through the Silverlight end using the TCP protocol. After the server receives the videos, it will detect who the videos are sent, call back a client to receive and display these videos.
Implementation
Duplex service contract Definition
[Servicecontract (callbackcontract = typeof (ichatservicecallback)] public interface ichatservice {[operationcontract] void sendvideo (uservideo );} [servicecontract] public interface ichatservicecallback {[operationcontract (isoneway = true)] void getvideos (list <uservideo> listvideos);} A data contract consists of three parts: the sender, receiver, and video stream, it is convenient for the server to determine and select the received callback handle.
[Datacontract] public class uservideo {[datamember] Public String username {Get; set;} [datamember] Public String partnername {set; get ;} [datamember] public byte [] videobyte {set; get ;}} since it is duplex, of course we also need to define a callback handle class for a client, which includes two attributes, one is the client name and the other is the callback handle.
public class ClientHandler {
public string Name { set; get; }
public IChatServiceCallBack Client { set; get; } }
The service implementation does not use a set of regular detection videos. Instead, it detects and calls back the client to receive the video each time a client uploads the video. The advantage of this is event-driven, more accurate than regular detection
Public class chatservice: ichatservice {static list <clienthandler> listofclienthandler = new list <clienthandler> (); Private Static list <uservideo> listvideos = new list <uservideo> (); ichatservicecallback client; public void sendvideo (uservideo) {console. writeline ("processing ing... "); listvideos. add (uservideo); client = operationcontext. current. getcallbackchannel <ichatservicecallback> (); If (listofclienthandler. where (M => M. name = uservideo. username ). count () = 0) {listofclienthandler. add (New clienthandler () {name = uservideo. username, client = client});} foreach (VAR item in listofclienthandler) {If (listvideos. where (M => M. partnername = item. name ). count ()> 0) {var videos = listvideos. where (M => M. partnername = item. name ). tolist (); item. client. getvideos (videos); console. writeline ("sending... "); listvideos. removeall (M => M. partnername = item. name); // Delete the video directly from the server after processing the video }}}}
The basic principle of the client is to first send a video and then define the callback function to process the server callback:
void btnSendVideo_Click(object sender, RoutedEventArgs e) { System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = new TimeSpan(0, 0, 0, 0, 200); timer.Tick += new EventHandler(timer_Tick); timer.Start(); } void timer_Tick(object sender, EventArgs e) { proxy = new ChatServiceClient(); proxy.GetVideosReceived += new EventHandler<GetVideosReceivedEventArgs>(proxy_GetVideosReceived); 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 += (se,ev) => { }; proxy.SendVideoAsync(userVideo); } void proxy_GetVideosReceived(object sender, GetVideosReceivedEventArgs e) { foreach (ChatService.UserVideo video in e.listVideos) { MemoryStream ms = new MemoryStream(video.VideoByte); BitmapImage bitmap = new BitmapImage(); bitmap.SetSource(ms); imagePartner.Source = bitmap; ms.Close(); } }
App. config Configuration
<system.serviceModel> <bindings> <netTcpBinding> <binding name="netTcpBindConfig" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647 " maxBufferSize="2147483647 " maxConnections="10" maxReceivedMessageSize="2147483647 "> <readerQuotas maxDepth="32" maxStringContentLength="2147483647 " maxArrayLength="2147483647 " maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="None"> </security> </binding> </netTcpBinding> </bindings> <services> <service behaviorConfiguration="Server.ChatServiceBehavior" name="Server.ChatService"> Legacy problems
1. Because the client regularly uploads video streams instead of persistent connections, you need to constantly call the server to upload videos, which consumes resources and sometimes causes the following exceptions, this is due to continuous connections.
2. the WCF transmission mode is configured with transfermode = "buffered", which is not suitable for stream transmission. Real-time performance still needs to be improved.
Http://files.cnblogs.com/wengyuli/chatTCPduplex.rar
Welcome to the discussion.