天天看點

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

前言:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

由于對戰視訊采用控制台程式,并沒有在伺服器運作,是以線上示範版本裡一進入顯示是顯示“未連結”的提示。

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

1:由于silverlight不支援點對點方式傳輸,是以隻能通過伺服器中轉方式進行。

2:視訊的傳輸是圖檔位元組,是以壓縮圖檔是相當必要的。

3:中間的服務選什麼?一開始我是在嘗試使用wcf的tcp方式,後來折騰配置檔案太痛苦,直接轉使用socket通訊,一來有性能優勢,二來減少折騰。

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

1:用戶端打開視訊

2:用戶端向遠端socket注冊[按規則定好的]編号[服務端根據編号查要轉發的對象]

3:服務端接收編号并注冊,收集一系列編号清單。

4:用戶端發送視訊

5:服務端接收視訊,并根據規則查找另一個編号,将視訊位元組轉發

6:另一個用戶端接收視訊并顯示

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

1:如何打開視訊

在siverlight中打開視訊相當的簡單,都有注釋,就不多解說了

代碼如下:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

        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]

        }

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

界面rectangle代碼:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

<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張是不一樣的哦],中間提示确認是否打開視訊就不截圖了:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

2:silverlight如何使用socket進行通訊

由于silverlight一般是不允許跨域通訊,是以,其socket通訊也要比普通的socket通訊麻煩一小點,不過這麻煩的小點隻表現在服務端。

下面進行代碼解析:以下代碼将一步扣一步,具體的連環扣如下:建立連結-》注冊編号-》開新線程待接收視訊-》收到視訊處理顯示。

2.1:與遠端建立連結:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

       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)//連結完成後

           //這裡要寫點什麼呢?

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

2.2:注冊編号[這裡的規則是“房間号+棋手顔色值”]

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

        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)

        {  

           //号碼發送過去了,接下這裡幹點什麼呢?

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

2.3:開新線程,等待接收對方視訊

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

       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)

            //如果收到視訊,我們要怎麼處理呢?            

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

2.4:将視訊顯示出來,需要用主線程來操作

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)
Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

        synchronizationcontext syn=synchronizationcontext.current;//擷取目前主線程

           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

            finally

                if (stream != null)

                    stream.close();

                }

                if (img != null)

                    img = null;

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

上面的imgvideo為:

<image height="160" horizontalalignment="left" margin="207,109,0,0" name="imgvideo" stretch="fill" verticalalignment="top" width="160" />

至此,我們連續完成了“打開視訊—》注冊—》等待接收-》接收時開主線程顯示”,我們提前看一下完成後接收時的效果圖:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

紅色塊是顯示視訊的區域,目前圖檔說明左側沒有開啟視訊,隻是開了接收,右側開了視訊,并發送視訊。

下面再順路看一下開啟的服務端中轉socket的運作:

Silverlight+WCF 實戰-網絡象棋最終篇之對戰視訊-上篇[用戶端開啟視訊/注冊編号/接收視訊](五)

ok,本節就先到此,下節我們再講“視訊圖檔的壓縮與發送”+服務端進行中轉流程

最後:謝謝大家對本系列的喜歡,謝謝支援~

ps:傳說點一下推薦會有10個園豆,喜歡麻煩點一下“推薦”,thank you very much!!

版權聲明:本文原創發表于部落格園,作者為路過秋天,原文連結:

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

繼續閱讀